Docker
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker的应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
参考:
末尾新建了一个群聊,给学习编程的小伙伴提供一个交流学习的中间件
docker概述
名词解释
镜像:image。docker 镜像就好比是一个模板,可以通过这个模板来创建容器服务,通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器:container。Docker利用容器技术,独立运行一个或者一个组应用 ,通过镜像来创建的。启动,停止,删除,基本命令。目前就可以把这个容器理解为就是一个简易的linux 系统
仓库:repository。仓库就是存放镜像的地方。仓库分为公有仓库和私有仓库。docker hub
概念 | 说明 |
---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 | Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 | Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 | Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 | Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 | Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
安装docker
yum remove docker ...
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
sudo docker run hello-world
docker images
yum remove docker-ce docker-ce-cli containerd.io
sudo rm -rf /var/lib/docker
run 的运行原理
本地有这个镜像
本地没有这个镜像
docker hub有这个镜像
docker hub没有这个镜像
run
docker会在本机寻找镜像
判断本机是否有这个镜像
下载这个镜像
去docker hub上下载这个镜像
下载这个镜像
返回错误
底层原理
docker 是怎么工作的?
docker 是一个client-server 结构的系统,docker 的守护进程运行在主机上,通过socket 从客户端访问,docker server 接收到一个client 的指令,就会执行这个命令
docker 为何比VM 快?
docker 有着更少的抽象层docker 利用的是宿主机的内核,VM 需要的是Guest OS
docker常用命令
帮助命令
docker version
docker info
docker command --help
镜像命令
docker images
REPOSITORY 镜像的仓库源
IAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像从创建时间
SIZE 镜像大小
-a -all
-q 只显示id
docker search command
docker pull 镜像名[:tag]
docker rmi 镜像名/ID
容器命令
我们有了镜像才可以创建容器
docker run [options] image
--name="Name"
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口
-p 主机端口: 容器端口
docker ps
-a 列出当前正在运行的容器
-n=? 显示最近创建的容器
-q 只显示容器的编号
exit
Ctrl+P+Q
docker rm 容器id
docker rm -f $(docker ps -aq)
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
常用其他命令
docker run -d 镜像名
查看日志
docker logs
查看进行信息
docker top 容器id
查看镜像的元数据
docker inspect 容器id
进入当前正在运行的容器
docker exec -it 容器id bashShell
docker attach -it 容器id bashShell
从容器内拷贝文件到宿主机
docker cp 容器id: 容器内路径 目的主机路径
docker可视化
docker run -d -p 8088:9000 \ -restart=always -v /var/run/docker.sock --privilieged=true portainer/portainer
docker镜像讲解
镜像是什么?
镜像是一种轻量级、可执行的独立软件包用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
docker镜像加载原理
UnionFS 联合文件系统
docker 的镜像实际上由一层一层的文件 系统组成,这种层级的文件系统UnionFS 。
bootfs : 主要包含bootloader 和kernel
rootfs : 在bootfs 之上包含的就是典型Linux 系统中的/dev , /proc , /bin 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如Ubuntu , Centos 等等。
对于一个精简的OS , rootfs 可以很小只需要包含最基本的命令,工具和程序库就可以了 因为底层直接用Host 的kernel ,自己只需要提供rootfs 就可以了。由此可见对于不同的linux 发行版, bootfs 基本是一致的, rootfs 会有差别,因此不同的发行版可以公用bootfs .
分层理解
所有的Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。 Docker 通过存储引擎( 新版本采用快照机制)的方式来实现镜像层堆栈, 并保证多镜像层对外展示为统一的文件系统。
下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点:
Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部! 这一层就是我们通常说的容器层,容器之下的都叫镜像层!
commit镜像
docker commit
docker commit -m='decription information' -a='author' 容器id 目标镜像名: [TAG]
容器数据卷
数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL ,容器删了,删库跑路!需求: MySQL 数据可以存储在本地!
容器之间可以有一个数据共享的技术! Docker 容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux 上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用方式
# 使用command挂载
docker run it -v 主机目录: 容器目录
可用docker inspect id 查看Mount 数据
具名挂载和匿名挂载
DockerFile
Dockerfile 就是用来构建docker 镜像的构建文件!
构建步骤:
- 编写一个
dockerfile 文件 docker build 构建成为一个镜像docker run 运行镜像docker push 发布镜像(dockerhub 、阿里云镜像仓库)
DockerFile构建过程
基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 指令从上到下顺序执行
# 注释- 每一个指令都会提交一个新的镜像层,并提交
dockerfile 是面向开发的
dockerfile : 构建文件,定义了一切的步骤,源代码dockerimages : 通过dockerfile 构建生成的镜像,最终发布和运行的产品dockercontainer : 容器就是镜像运行起来提供服务的
DockerFile指令
FROM # 基础镜像
MAINTAINER # 指定维护者信息
RUN # 镜像运行时需要运行的命令
ADD # COPY文件,会自动解压
WORKDIR # 设置为当前工作目录,默认是根目录
VOLUME # 设置卷,挂载主机目录
EXPOSE # 指定对外的端口
CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动的时候要运行的命令,可以直接追加命令
ONBUILD # 当构建一个被继承的dockerfile这个就会运行ONBUILD指令
COPY # 类似ADD,将文件拷贝到镜像中
ENV # 构建时候设置环境变量
示例
FROM centos
MAINTAINER liuhao<2226958871@qq.com>
ENV MYPATH /user/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
运行
sudo docker build -f mydockerfile-centos -t mycentos:0.1 .
删除镜像docker rmi 0a13c25d4106 时出现Error response from daemon: conflict: unable to delete 0a13c25d4106 (must be forced) - image is being used by stopped container e75090bb6845
此时我们必须先删除容器,再删除镜像
删除容器docker rm e75090bb6845
删除镜像docker rmi 0a13c25d4106
docker history container_id
小tips: CMD 和ENTRYPOINT 的区别
FROM centos
CMD ["ls", "-a"]
lh@lh-virtual-machine:~/dockerfile$ sudo docker build -f dockerfile-test -t cmdtest .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : CMD ["ls", "-a"]
---> Running in f91fed361f85
Removing intermediate container f91fed361f85
---> a0f87e6e2236
Successfully built a0f87e6e2236
Successfully tagged cmdtest:latest
lh@lh-virtual-machine:~/dockerfile$ sudo docker run -it cmdtest
. .dockerenv dev home lib64 media opt root sbin sys usr
.. bin etc lib lost+found mnt proc run srv tmp var
sudo docker run -it cmdtest -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
想追加一个命令-l ,即ls -al 。在CMD 的情况下,-l 替换了CMD ["ls", "-a"] 命令,而-l 不是一个命令,所以会报错
使用ENTRYPOINT
lh@lh-virtual-machine:~/dockerfile$ cat dockfile-en
FROM centos
ENTRYPOINT ["ls", "-a"]
lh@lh-virtual-machine:~/dockerfile$ sudo docker run -it entest -l
total 56
drwxr-xr-x 1 root root 4096 Dec 25 07:19 .
drwxr-xr-x 1 root root 4096 Dec 25 07:19 ..
-rwxr-xr-x 1 root root 0 Dec 25 07:19 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Dec 25 07:19 dev
drwxr-xr-x 1 root root 4096 Dec 25 07:19 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Sep 15 14:17 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 377 root root 0 Dec 25 07:19 proc
dr-xr-x--- 2 root root 4096 Sep 15 14:17 root
drwxr-xr-x 11 root root 4096 Sep 15 14:17 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Dec 25 07:19 sys
drwxrwxrwt 7 root root 4096 Sep 15 14:17 tmp
drwxr-xr-x 12 root root 4096 Sep 15 14:17 usr
drwxr-xr-x 20 root root 4096 Sep 15 14:17 var
实战:制作一个Tomcat 镜像
准备好镜像文件Tomcat 压缩包和jdk 压缩包
编写dockerfile 文件
FROM centos
MAINTAINER liuhao<2226958871@qq.com>
COPY README.md /usr/local/README.md
ADD jdk-8u271-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.72.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_271
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.72
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.72
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.72/bin/startup.sh && tail -F /url/local/apache-tomcat-8.5.72/bin/logs/catalina.out
构建镜像
sudo docker run -d -p 9090:8080 --name lh -v /home/lh/build/tomcat/test:/url/local/apache-tomcat-8.5.72/webapps/test -v /home/lh/build/tomcat/tomcatlogs:/url/local/apache-tomcat-8.5.72/logs fdocker
发布镜像
dockerhub 提交
登陆账号
docker login -u username
提交镜像
docker push name/image:[tag]
阿里云容器服务提交
不作概述
删除所有镜像
sudo docker rmi -f $(sudo docker images -aq)
Docker网络
每启动一个docker 容器,docker 都会给docker 容器分配一个ip ,只要我们安装了docker ,就会有一个网卡docker0 桥接模式,使用的技术是evth-pair 技术
evth-pair 技术:一对虚拟设备接口,一端连接着协议,一端彼此相连,正因为有这个特性,evth-pair 充当着桥梁,连接各种虚拟网络设备。
容器和容器之间是可以ping 通的
所有的容器不指定网络的情况下,都是docker0 路由的,docker 会给我们的容器分配一个默认的可用ip
–link
思考一个场景:我们编写了一个微服务,database url=ip ,项目不重启,数据库ip 换掉了,我们希望可以处理这个问题,可以通过名字来访问容器
docker run -d -P --name tomcat03 --link tomcat02
--link 就是我们在hosts 配置中增加了一个tomcat02 的一个映射
docker0 ,不支持容器名访问。此时可以使用自定义网络
自定义网络
网络模式
bridge :桥接模式。在docker 上搭桥none :不配置网络host :和Linux 宿主机共享网络container : 容器网络互通
docker run -d -P --name tomcat01 --net bridge tomcat
查看docker network 工具
sudo docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
查看存在的网络模式
sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
48e87b864c06 bridge bridge local
668c70016c72 host host local
b38af4bd171b none null local
创建自定义网络
sudo docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which to copy the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
网络连通
实现两个网段互通?让其中一个网段的容器访问另外一个网段的容器?
sudo docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
docker network connect network_segment container
即所谓的一个容器,两个IP
“我们都是平凡人”,新建了一个群聊,大家可以加入一起交流学习经验,我也不太懂什么这的那的,只希望大家一起进步一起学习一起努力就行了,来者皆迎。
|