Docker基础
Docker安装
Docker的基本组成
镜像(image):
docker的镜像就好比一个模板,可以通过这个模板来创建容器服务。一个镜像可以启动多个容器。
容器(container):
Docker利用容器技术独立运行一个或一组应用。容器是通过镜像来创建的。容器具有启动、停止、删除等基本命令。目前可以把这个容器理解为一个简易的linux系统。
仓库(repository):
仓库是存放镜像的地方。
仓库分为公有仓库和私有仓库。
安装Docker
# 系统内核要在 3.10 以上
[xdd@localhost ~]$ uname -r
4.18.0-193.19.1.el8_2.x86_64
安装
[官方帮助文档](Install Docker Engine on CentOS | Docker Documentation)
# 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 # 建议用阿里云的
# 建议先更新yum软件包所有
yum makecache fast
# 4、安装docker
sudo yum install docker-ce docker-ce-cli containerd.io
# 5、启动docker
sudo systemctl start docker
# 6、使用docker version确定安装成功
docker version
# 7、启动hello world 测试
sudo docker run hello-world
# 8、重看刚刚下载的镜像
docker images
卸载
# 1、卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
# 2、删除资源
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
阿里云镜像加速
2、找到镜像加速地址
注:每个账号都有自己的镜像加速地址,建议用自己的,都是免费的。
3、配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://684n024r.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker run的运行流程
Docker 底层原理
Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在宿主机上,通过Socket从客户端访问。
DockerServer接收到Docker-Client的命令就会去执行这个命令!
Docker为什么比VM快?
1、Docker有着比虚拟机更少的抽象层。
2、Docker使用的是宿主机的内核,VM需要Guest OS。
所以说,新建一个容器的时候,Docker不需要向VM一样重新加载一个操作系统内核,而是直接利用宿主机的操作系统。
Docker的常用命令
帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器等信息
docker 命令 --help # 帮助命令
帮助文档的地址:Docker命令帮助文档
镜像命令
docker images 查看本地的镜像
[xdd@localhost ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 6 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a, --all 列出所有的镜像
-q, --quiet 只显示ID
docker search 搜索镜像
[xdd@localhost ~]$ docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11385 [OK]
mariadb MariaDB Server is a high performing open sou… 4321 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 846 [OK]
# 可选项
--filter=STARS=3000 # 搜索stars不小于3000的
docker pull 下载镜像
# 下载镜像 docker pull 镜像名[:tag
[xdd@localhost ~]$ docker pull redis
Using default tag: latest # 如果不写tag默认就是latest
latest: Pulling from library/redis
a330b6cecb98: Pull complete # 分层下载,docker image的核心
14bfbab96d75: Pull complete
8b3e2d14a955: Pull complete
5da5e1b21a2f: Pull complete
6af3a5ca4596: Pull complete
4f9efe5b47a5: Pull complete
Digest: sha256:e595e79c05c7690f50ef0136acc9d932d65d8b2ce7915d26a68ca3fb41a7db61
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest # 真实地址 docker pull redis就等价于docker pull docker.io/library/redis:latest
docker rmi 删除镜像
docker rmi -f 镜像ID # 删除指定的镜像
docker rmi -f 镜像ID 镜像ID 镜像ID # 删除多个镜像
docker rmi -f $(docker images -aq) # 删除所有镜像
容器命令
说明:有了镜像才能创建容器
新建容器并启动
docker run [可选参数] image
# 可选参数
--name="Name" 容器名字,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器端口
-p ip:主机端口:器端口
-p 主机端口:器端口(常用)
-p 容器端口
-P 随机指定端口
# 新建并启动容器
[xdd@localhost ~]$ docker run -it centos /bin/bash # 测试启动一个centOS
[root@b9d8b396f964 /]# # 此时已经进入到容器内的centOS了
[root@b9d8b396f964 /]# exit # 退出容器
列出所有运行的容器
# docker ps # 列出正在运行的容器
# 可选参数
-a # 列出正在运行的容器+历史运行的容器
-n=1 # 显示数量
-q # 只显示ID
[xdd@localhost ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[xdd@localhost ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9d8b396f964 centos "/bin/bash" 4 minutes ago Exited (130) About a minute ago intelligent_noether
[xdd@localhost ~]$ docker ps -aq
b9d8b396f964
退出容器
exit # 退出且停止容器
Ctrl + P + Q # 退出不停止
删除容器
docker rm 容器ID # 删除指定容器,不能删除正在运行的容器,需要加 -f
docker rm -f $(docker ps -aq) 删除所有的容器
启动和停止容器操作
docker start 容器ID # 启动容器
docker stop 容器ID # 停止容器
docker restart 容器ID # 重启容器
docker kill 容器ID # 强制停止容器
常用的其他命令
后台启动
# docker run -d 镜像名
# 常见的问题:容器后台运行,必须要有一个前台进程,如果docker发现没有应用就会自动停止
查看日志
docker logs -ft [--tail number]
查看容器中的进程信息
# docker top 容器ID
查看容器的元数据
# docker inspect 容器ID
进入正在运行的容器
# docker exec -it 容器ID baseshell # 进入容器后打开一个新的终端
# docker attach 容器ID # 进入容器正在运行的终端
从容器内拷贝文件到主机上
# docker cp 容器ID:容器内路径 主机路径
Docker镜像
镜像是什么?
镜像是一种轻量级的课独立执行的软件包,用来打包软件的运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量、库和配置文件。
Docker镜像加载原理
UnionFS (联合文件系统)
Union文件系统(UnionFS) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。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等等。
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
针对DockerFile,每一次RUN 都会基于基础镜像,作出一个新的images
理解:
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
例如:基于Ubuntu 16.04创建一个新的镜像,这就是这个镜像的第一层,如果在该镜像中添加Python的包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三层。此时这个镜像就包含三个镜像层。
在添加额外的镜像层的同时,镜像始终保持的是当前的所有的镜像的组合,如下图所示,每个镜像层包含三个文件,那么这个镜像就包含这六个文件。
特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层镜像加载到镜像顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层。
commit镜像
docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:TAG
如果你想要保存当前容器的状态,就可以通过commit命令来提交,获得一个镜像。
相当于VM的快照
容器数据卷
docker的理念:将应用和环境打包成一个镜像!
使用数据卷
- 方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录 镜像名称 baseshell
实战:安装MySQL
# 获取镜像
docker pull MySQL:5.7
# 启动镜像,并做数据挂载
-d: 后台启动
-p:端口映射
-v:数据卷挂载
-e:环境配置
--name 容器名字
[xdd@localhost ~]$ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xdd123 --name mysql01 mysql:5.7
[xdd@localhost ~]$ cd /home/mysql
[xdd@localhost mysql]$ ls
conf data
[xdd@localhost mysql]$ cd data
[xdd@localhost data]$ ls # 可以看到本机目录内已经有了MySQL的数据
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
具名挂载和匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume情况
[xdd@localhost data]$ docker volume ls
DRIVER VOLUME NAME
local 704cc99e505593cee001007a962f36f917d4a9cc926ebcb531bbce237ffc1c32
local b317958b15d01dfdf6d328e31d8bffa83d142087a2bbfad1b1a67f43bb9305bf
local e6db9cc213d157ca3d252eb747e4379429897869c3b63e387d87b4d672913a1c
# 这种就是匿名挂载,我们-v后面只写的容器路径没写本机路径。
# 具名挂载
# -v 数据卷名称:容器内路径
docker run -d -P --name nginx02 -v nginx-config:/etc/nginx nginx
[xdd@localhost data]$ docker volume ls
DRIVER VOLUME NAME
local 704cc99e505593cee001007a962f36f917d4a9cc926ebcb531bbce237ffc1c32
local b317958b15d01dfdf6d328e31d8bffa83d142087a2bbfad1b1a67f43bb9305bf
local e6db9cc213d157ca3d252eb747e4379429897869c3b63e387d87b4d672913a1c
local nginx-config
[xdd@localhost data]$ docker volume inspect nginx-config
[
{
"CreatedAt": "2021-09-11T10:43:19-04:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx-config/_data", # 真实路径
"Name": "nginx-config",
"Options": null,
"Scope": "local"
}
]
# 所有容器卷没有指定目录的情况下都在/var/lib/docker/volumes/卷名/_data目录下
# 通过具名挂载可以很方便的找到一个卷
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v 宿主机路径:容器内路径 # 指定路径挂载
拓展:
# 通过 -v 容器内路径:ro rw 来改变读写权限
ro:readonly # 只读,只能通过宿主机来操作,容器内部无法操作
rw:readwrite # 可读可写
# --volumes-from 容器名 容器间数据挂载
DockerFile
DockerFile是用来构建docker镜像的文件,是一中命令行参数脚本!
构建步骤:
1、编写一个DockerFile文件
2、docker builde 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像
DockerFile的构建过程
基础知识:
1、每个保留关键字(指令)都必须是大写的
2、执行顺序是从上到下
3、# 表示注释
4、每一个指令都会提交创建一个镜像层并提交
DockerFile的指令
FROM # 基础镜像,一切从这里开始搭建
MAINTAINER # 维护者信息,姓名+邮箱
RUN # 镜像构建的时候要运行的命令
ADD # COPY文件到镜像内
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 端口配置
CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动的时候要运行的命令,启动时可以追加命令
ONBUILD # 当构建一个被继承 DockerFIle 这个时候就会运行OBUILD的指令
COPY # 类似ADD,将文件拷贝到镜像中
ENV # 构建的时候设置环境变量
实战测试
DockerFile文件内容
FROM centos
MAINTAINER XDD<2033556885@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
# 构建镜像
-f # 文件路径
-t # 镜像名
docker build -f DockerFile -t mycentos:0.1 . # 注意最后有个.
[xdd@localhost dockerfile]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 f1b88d55382e About a minute ago 309MB
centos latest 300e315adb2f 9 months ago 209MB
[xdd@localhost dockerfile]$ docker run -it mycentos:0.1
[root@d925ccc914c9 local]# # 可以看到启动后自动进入到了工作目录
# 查看镜像的构建过程
[xdd@localhost dockerfile]$ docker history f1b88d55382e
IMAGE CREATED CREATED BY SIZE COMMENT
f1b88d55382e 4 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
31198a5b1d91 4 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
72d18f502662 4 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
142e3a07744c 4 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
a5220ffd18ed 4 minutes ago /bin/sh -c yum -y install net-tools 30.5MB
52d637283fb7 4 minutes ago /bin/sh -c yum -y install vim 69.5MB
c063b2e3cba9 4 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
f96e37ee6246 4 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
96b0c10caa58 4 minutes ago /bin/sh -c #(nop) MAINTAINER XDD<2033556885… 0B
300e315adb2f 9 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 9 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
Docker网络
实战:制作自己的tomcat镜像
1、准备jdk和tomcat压缩包
-rw-r--r--. 1 root root 9621672 9月 12 05:28 apache-tomcat-9.0.52.tar.gz
-rw-r--r--. 1 root root 9621672 9月 12 05:28 jdk-8u161-linux-x64.tar.gz
2、编写Dockerfile文件
FROM centos
MAINTAINER xdd<2033556885@qq.com>
COPY README.txt /usr/local/README.txt
ADD jdk-8u161-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.52.tar.gz /usr/local/
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-9.0.52
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.52
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.52/bin/startup.sh
3、构建镜像
docker build -t diytomcat .
4、启动镜像
docker run -d -p 9898:8080 --name xddtomcat -v /home/xdd/build/tomcat/test:/usr/localapache-tomcat-9.0.52/webapps/test -v /home/xdd/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.52/logs diytomcat
docker run -it -p 9898:8080 --name xddtomcat -v /home/xdd/build/tomcat/test:/usr/localapache-tomcat-9.0.52/webapps/test -v /home/xdd/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.52/logs diytomcat
5、访问测试
6、发布项目
由于做了卷挂载所以直接在本地编写项目就可以了