Docker概述
docker: 码头工人
Docker出现的原因
-
产品的开发和上线是两套环境,应用环境和应用配置。
-
从开发到运维存在的问题:版本更新,导致服务不可用,对于运维来说,很考验人。
-
环境配置很麻烦,每个机器都要部署环境(集群Redis, ES, Hadoop…),费时费力。
-
发布一个项目(jar + (Redis MySql jdk ES)),项目能不能带上环境安装打包。
-
使用docker开发流程:
java–>jar+环境—>打包项目带上环境(镜像)—>Docker仓库:商店----->下载发布的镜像–>直接运行即可
Docker历史
-
在容器技术出来之前,我们都是使用虚拟机技术;
-
虚拟机:在Window中装一个Vmware,通过这个软件可以虚拟出一台或者多台电脑,比较笨重;
-
虚拟机属于虚拟化技术,Docker的容器技术,也是一种虚拟化技术;
-
Docker:隔离,镜像(只需要最核心的环境) 十分小巧,运行镜像就可以了;
-
Docker相对虚拟机十分轻巧;
-
Docker是基于Go语言开发的;
-
DockerHub类似Github。
Docker能干嘛
虚拟机技术
缺点:
- 资源占用多
- 冗余步骤多
- 启动慢
容器化技术
容器化技术不是模拟的一个完整的操作系统。
Docker和虚拟机技术的不同:
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟硬件,更轻便。
- 每个容器间是互相隔离的,每个容器内部都有一个属于自己的文件系统,互不影响。
DevOps(开发、运维)
-
应用更快速的交付和部署
-
更便捷的升级和括缩容
-
更简单的系统运维
-
更高效的计算资源利用
- Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
Docker的基本组成
1、镜像(image):
Docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像—》run—》容器(提供服务器)。
通过镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的。)
2、容器(container):
Docker利用容器技术,独立运行一个或者一组应用。
3、启动、停止、删除
把容器理解为简易的linux系统。
4、仓库(repository):
仓库是存放镜像的地方。
仓库分为共有仓库和私有仓库。
安装Docker
安装
1、卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、需要的安装包
yum install -y yum-utils
3、设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #默认是国外的
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #推荐使用阿里云的
4、安装Docker
- 更新yum软件包索引
asd
# docker-ce 社区版 ee企业版
yum install docker-ce docker-ce-cli containerd.io
5、启动Docker
systemctl start docker
docker version # 查看docker版本
6、Hello world
7、查看下载的hello-world镜像
卸载docker
#1、卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
#2、删除资源
sudo rm -rf /var/lib/docker
# /var/lib/docker docker的默认工作路径
阿里云镜像加速
1、容器服务
2、配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://1dy5z6su.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
按步骤执行
Hello-world流程
底层原理
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。
DockerServer 接收到Docker-Client的指令,就会执行这个命令!
Docker为什么比虚拟机快?
1、Docker比虚拟机少了很多抽象层
2、Docker利用的是宿主机的内核,VM需要的是Guest OS
3、新建一个容器的时候,Docker不需要虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,加载速度慢,分钟级别的;Docker利用宿主机的操作系统,省略了这个复杂的过程,秒级。
Docker的常用命令
帮助命令
docker version # 显示Docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
镜像命令
- docker images 查看所有镜像
docker images #查看所有镜像
[root@izbp1bl327dijs0vtjs2kuz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 3 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
Options:
-a, --all Show all images (default hides intermediate images)列出所有镜像
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show image IDs只显示镜像的id
-
docker search 搜索命令
-
docker pull 下载镜像
命令说明:
[root@izbp1bl327dijs0vtjs2kuz ~]# docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output
命令使用:
# 下载镜像 docker pull 镜像名[:tag]
[root@izbp1bl327dijs0vtjs2kuz ~]# docker pull mysql
Using default tag: latest #默认是latest
latest: Pulling from library/mysql
69692152171a: Pull complete #分层下载,docker image的核心 联合文件系统
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
f7fddf10c2c2: Pull complete
16415d159dfb: Pull complete
0e530ffc6b73: Pull complete
b0a4a1a77178: Pull complete
cd90f92aa9ef: Pull complete
Digest: sha256:d50098d7fcb25b1fcb24e2d3247cae3fc55815d64fec640dc395840f8fa80969 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址
# 两个命令等价
docker pull mysql
docker pull docker.io/library/mysql:latest
#指定版本下载
docker pull mysql:5.7
- docker rmi 删除镜像
[root@izbp1bl327dijs0vtjs2kuz ~]# docker rmi --help
Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
Remove one or more images
Options:
-f, --force Force removal of the image
--no-prune Do not delete untagged parents
容器命令
说明:有了镜像才可以创建容器,linux下下载一个
docker pull centos
- docker run 新建容器并启动
[root@izbp1bl327dijs0vtjs2kuz ~]# docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
Options:
--name string Assign a name to the container,容器名称
-d, --detach Run container in background and print container ID 后台运行方式
-p, --publish list Publish a container's port(s) to the host
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
-p 随机指定端口
-P, --publish-all Publish all exposed ports to random ports
-it 使用交互方式运行,进入容器查看内容
[root@izbp1bl327dijs0vtjs2kuz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 3 months ago 13.3kB
centos latest 300e315adb2f 6 months ago 209MB
# 启动并进入容器
[root@izbp1bl327dijs0vtjs2kuz ~]# docker run -it centos /bin/bash
# 查看容器内的centos
[root@8ddd2c5ed95d /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 从容器中退回主机
[root@8ddd2c5ed95d /]# exit
exit
[root@izbp1bl327dijs0vtjs2kuz ~]#
- 列出所有运行的容器
[root@izbp1bl327dijs0vtjs2kuz ~]# docker ps --help
Usage: docker ps [OPTIONS]
List containers
Options:
-a, --all Show all containers (default shows just running)列出当前正在
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display container IDs
-s, --size Display total file sizes
- 退出容器
exit # 容器停止并退出
Ctrl + P + Q #容器不停止退出
- 删除容器
docker rm 容器id #删除指定容器、不能删除正在运行的容器,如果强制删除 rm -f
docker rm -f $(docker ps -aq) #删除所有的容器
- 启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
常用其他命令
- 后台启动容器
# 命令 docker run -d 镜像名
[root@izbp1bl327dijs0vtjs2kuz ~]# docker run -d centos
2b76bc5def15e49d0a051adc692c0c5d2d8b375dadc9f6123a30710a41cb73d8
[root@izbp1bl327dijs0vtjs2kuz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 查看日志
docker logs -f -t --tail 容器
# 显示日志
--tf #显示日志
--til number # 要显示的日志条数
- 查看容器中的进程信息
# docker top 容器id
[root@izbp1bl327dijs0vtjs2kuz ~]# docker top 8ddd2c5ed95d
UID PID PPID C STIME TTY TIME CMD
root 20680 20645 0 22:29 pts/0 00:00:00 /bin/bash
- 查看镜像的元数据
# docker inspect 容器id
docker inspect 8ddd2c5ed95d
- 进入正在运行的容器
docker exec -it 容器id bashShell
# 测试
[root@izbp1bl327dijs0vtjs2kuz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ddd2c5ed95d centos "/bin/bash" 20 hours ago Up 18 hours keen_yonath
[root@izbp1bl327dijs0vtjs2kuz ~]# ^C
[root@izbp1bl327dijs0vtjs2kuz ~]# docker exec -it 8ddd2c5ed95d /bin/bash
[root@8ddd2c5ed95d /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@8ddd2c5ed95d /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jun08 pts/0 00:00:00 /bin/bash
root 29 0 0 08:34 pts/1 00:00:00 /bin/bash
root 44 29 0 08:35 pts/1 00:00:00 ps -ef
# 方式2
docker attach 容器id
# docker attach 进入容器正在执行的终端,不会启动新的进程
# docker exec 进入容器后开启一个新的终端,可以在里面操作(常用)
- 从容器内拷贝文件到主机
docker cp 容器id:容器内路径 目的主机路径
小结
- 端口暴露的概念
安装tomcat
# 官方使用
# 该命令一搬用来测试,用完即删除容器
docker run -it --rm tomcat:9.0
# 我们之前启动的都是后台,停止了容器之后,容器还是可以查到
可视化Portainer
- portainer
- Rancher(CI/CD)
portainer图形化界面管理工具!提供一个后台面板供我们操作。
- 安装
docker volume create portainer_data
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
- 查看运行状态
[root@izbp1bl327dijs0vtjs2kuz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4fdde5aa50e2 portainer/portainer-ce "/portainer" 45 seconds ago Up 43 seconds 0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp portainer
8ddd2c5ed95d centos "/bin/bash" 24 hours ago Up 22 hours keen_yonath
-
远程访问http://ip:9000/(ip:服务器的ip地址)
-
设置用户和密码
-
可以显示所有的镜像和容器
-
所有的容器
Docker镜像详解
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时的库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来!
如果得到镜像:
- 从远程仓库下载
- 自己制作一共镜像 DockerFile
Docker镜像加载原理
UnionFS 联合文件系统
UnionFS 联合文件系统:是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动的时候会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载期和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在bootfs之上。包含的就是典型Linux系统中的/dev, /proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Gipflp2-1624242048560)(…/image/image-20210609213112543.png)]
对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的Kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
分层理解
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层。
commit镜像
docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
[root@izbp1bl327dijs0vtjs2kuz ~]# docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Options:
-a, --author string Author (e.g., "John Hannibal Smith")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
- 测试
# 1、启动一个默认的tomcat
2、默认的tomcat没有webapps应用。官方的镜像默认webapps下面没有文件
3、拷贝进去基本的文件
4、将操作过的容器通过commit提交为一个镜像!
???虚拟机快照
容器数据卷
容器数据卷概念
- 如果数据都在容器中,那么容器删除,数据就会丢失!需求:数据可以持久化
- MySQL,容器删了,删除跑路。需求:MySQL数据可以存储在本地
- 容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
- 这就是卷技术,目录的挂载,将我们容器内的目录,挂载到Linux上面!
- 总结:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
[root@izbp1bl327dijs0vtjs2kuz home]# docker run -it -v /home/dockertest:/home centos
[root@izbp1bl327dijs0vtjs2kuz home]# docker inspect b7c33af4a6af
- 挂载成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QcfDtn7I-1624242048566)(…/image/image-20210610123414301.png)]
-
测试文件同步
在主机上新建
test.txt
查看容器指定目录变化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k1G0WJpk-1624242048567)(…/image/image-20210610155558616.png)]
MySQL同步数据
- 下载Docker镜像
[root@izbp1bl327dijs0vtjs2kuz dockertest]# docker pull mysql:5.7
5.7: Pulling from library/mysql
69692152171a: Pull complete
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
a023ae82eef5: Pull complete
e76c35f20ee7: Pull complete
e887524d2ef9: Pull complete
ccb65627e1c3: Pull complete
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
- 官方启动说明
Starting a MySQL instance is simple:
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
… where some-mysql
is the name you want to assign to your container, my-secret-pw
is the password to be set for the MySQL root user and tag
is the tag specifying the MySQL version you want. See the list above for relevant tags.
# 测试
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
[root@izbp1bl327dijs0vtjs2kuz dockertest]# docker run -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
6af8276c3582d5d9ff5ab78e79da167c8d174d6ad93de7058e86604519362991
# 启动成功之后,测试能否连接容器中的数据库
# 连接到服务器的3310映射和容器内的3306映射
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok
具名和匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/niginx nginx
# 匿名挂载时,-v 只写了容器内的路径,没有写容器外的路径
# 具名挂载
# 查看卷
docker volume inspect 卷名
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
- 拓展
# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly
rw readwrite
docker run -d -p --name nginx01 -v /etc/niginx:ro nginx
docker run -d -p --name nginx01 -v /etc/niginx:rw nginx
# ro 说明这个路径只能通过宿主机来操作,容器内部是无法操作的
初识DockerFile
DockerFile就是用来构建docker镜像的构建文件!命令脚本。
通过脚本可以生成镜像。
镜像是一层一层的,脚本是一行一行命令,每个命令都是一层!
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "----end---"
CMD /bin/bash
- 创建镜像
[root@izbp1bl327dijs0vtjs2kuz docker-test-volume]# docker build -f dockerfile1 -t evan/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : VOLUME ["volume01", "volume02"]
---> Running in 3c5c7447d07c
Removing intermediate container 3c5c7447d07c
---> b8f9a87cadbe
Step 3/4 : CMD echo "----end---"
---> Running in 3737153b4862
Removing intermediate container 3737153b4862
---> ea56bbc1b68a
Step 4/4 : CMD /bin/bash
---> Running in d27596b407d2
Removing intermediate container d27596b407d2
---> 243ddc554870
Successfully built 243ddc554870
Successfully tagged evan/centos:latest
-
生成成功
-
运行容器
这是一个匿名挂载
-
查看卷挂载的路径
-
查看宿主机挂载的目录
假设构建镜像的时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径
linux中mount文件系统????
数据卷容器
多个mysql同步数据
结论:
-
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
-
但是一旦持久化到了本地,这个时候,本地的数据是不会删除的。
DockerFile
DockerFile就是用来构建docker镜像的构建文件!命令参数脚本!
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像 (DockerHub, 阿里云镜像仓库)
基础知识
1、每个保留关键字(指令)必须是大写字母
2、从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交
-
dockerfile是面向开发的,发布项目,做镜像,就需要编写dockerfile文件。
-
Docker镜像逐渐成为企业交付的标准,必须要掌握
-
dockerfile:构建文件,定义了一切的步骤,是源代码
-
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!
-
Docker容器:容器就是镜像运行起来提供服务。
Dockerfile指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat压缩包,添加内容
WORKDIR #镜像工作目录
VOLUME #挂载的目录
XEPOSE #指定暴露端口
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承Dockerfile 这个时候就会运行 ONBUILD 的指令。触发指令。
COPY #类似ADD,将我们文件拷贝到镜像中
ENV #构建的时候设置环境变量
实战测试
Docker Hub中99%的镜像都是从这个基础镜像过来的(FROM scratch),然后配置需要的软件和配置来进行构建。
1、编写dockerfile
FROM centos
MAINTAINER evan<evantaoo@163.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
[root@izbp1bl327dijs0vtjs2kuz dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/10 : FROM centos
---> 300e315adb2f
Step 2/10 : MAINTAINER evan<evantaoo@163.com>
---> Running in 42b3d8d45d45
Removing intermediate container 42b3d8d45d45
---> 2bbbbd0728a9
Step 3/10 : ENV MYPATH /usr/local
---> Running in 8632ea951554
Removing intermediate container 8632ea951554
---> 52a22408b71a
Step 4/10 : WORKDIR $MYPATH
---> Running in d783c4fc97a7
Removing intermediate container d783c4fc97a7
---> f25d3ebf41ea
Step 5/10 : RUN yum -y install vim
---> Running in 524388eb7402
..............
# 创建成功
Successfully built 3258a358bfd8
Successfully tagged mycentos:0.1
- 列出镜像本地的变更历史