Docker是一个开源的引擎,它提供了为应用程序创建轻量级/可移植/高效的容器方案。支持部署到本地和云平台环境。使用Docker有很多好处,比如更快的交付和部署,更高效的资源利用,更轻松的迁移。它的应用场景包括Web应用的自动化打包部署,自动化测试,持续集成等。
docker的核心: 镜像、容器、仓库
Docker中的镜像类似于虚拟机的镜像,可以理解为一个只读的模板。比如,一个镜像包含一个基本操作系统环境,或者包含某个应用程序正确运行所需的运行环境。镜像是创建Docker容器的基础,通过镜像的版本控制,Docker提供了十分简单的机制来创建和更新镜像,也可以直接下载已经做好的应用镜像,并直接使用。
Docker容器类似一个轻量级的沙盒,Docker利用容器来运行和隔离应用,容器是从镜像创建的应用运行示例,可以对它进行启动,停止,删除等操作。
可以理解容器为一个简易版的Linux操作系统环境,包括某些应用程序打包而成的盒子。
Docker仓库类似代码仓库,是Docker用来集中存放镜像的地方。Docker仓库根据镜像是否公开分为公开仓库和私有仓库,目前最大的公开仓库是官方提供的Docker Hub,其中存放了大量的镜像供用户下载。同时,国内不少云服务提供商也提供了仓库的本地源,可以提高稳定的国内访问。
关于私有仓库,用户可以自行搭建本地仓库,用于维护私有的镜像。
镜像构建时,会一层一层的构建,前一层是后一层的基础,每一层构建完就不会发生改变,后一层所有的改变都不会影响前一层的。比如删除前一层的文件,其实并不是删除了前一层的文件,只是标记为已删除,在容器运行的时候,不会看到这个文件,但是实际上文件还存在。
分层存储的特征让镜像的复用变得容易,比如可以以之前建好的镜像作为基础层,然后逐步添加新的层,以定制自己所需的内容。
删除旧版本的 Docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装所需的软件包
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
设置docker默认的镜像仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装docker
sudo yum install docker-ce docker-ce-cli containerd.io
启动docker
sudo systemctl start docker
以下代码是设置阿里云的 docker 镜像仓库
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://y5j5hcnv.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker images # 查看所有模板
docker pull tomcat # 从远程仓库拉取 image 镜像
docker rmi tomcat # 删除某个镜像
docker run -d --name mytomcat -p 80:8080 tomcat # 运行docker image 镜像
docker exec -it tomcat /bin/bash # 进入到容器中执行命令
docker ps # 查看正在运行的 container
docker kill tomcat # 杀死进程
docker build -t vitshop-image # 构建 image 镜像
docker logs -f vitshop # 查看日志
docker container ls -a # 查看所有的container
docker container rm tomcat # 删除container
docker inspect tomcat # 查看 image 镜像详细信息
docker history tomcat # 查看镜像历史
docker volume ls # 查看所有的 volume
docker volume inspect tomcat # 查看 volume 详情
docker volume create # 创建volume
docker volume rm # 删除 volume
docker start mytomcat # 启动已有的container
docker官网命令集合
Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
FROM centos # 基于什么镜像之上构建自己的自定义镜像
RUN # 用于执行后面命令,RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
CMD # 类似于 RUN 命令,用于运行程序。 CMD在docker run 时运行。 run 是在docker build时运行
COPY # 复制指令,从上下文目录中复制文件或者目录到容器的制定位置
ADD # 跟复制命令使用格式一致(同样的需求下,官方建议使用 copy)
VOLUME # 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载匿名的数据卷。 做持久化数据
ENTRYPOINT # 类似于 cmd 命令但其不会被 docker run的命令行参数指定的指令所覆盖,而且这些命令行的参数会被当做参数传给
# ENTRYPOINT 所指定的程序,但是如果运行 docker run 时候使用了 --entrypoint 选项,
# 此选项的参数可当做要运行的程序覆盖 ENTRYPOINT 指定的程序
# 优点: 在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数
# 注意: 如果 Dockerfile 文件中存在多个 ENTRYPOINT 指令,仅最后一个生效。
ENV # 设置环境变量,定义了环境变量,那么在后续的指令中就可以使用这个变量。
ARG # 构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,
# 也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
# 构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
EXPOSE # 仅仅只是声明端口。帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
# 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
WORKDIR # 指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在(WORKDIR 指定的工作目录,必须是提前创建好的)
# docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
USER # 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
HEALTHCHECK # 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
ONBUILD # 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行
# (假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,
# 这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
以springboot项目为例:把打包好的 springboot.jar 放入服务器自定义目录中,并创建 Dockerfile 文件。
mkdir vitshop-image # 创建自定义目录,
vim Dockerfile # 创建 Dockerfile 文件
编辑 Dockerfile 文件
FROM openjdk:8
MAINTAINER itcrazy2016
LABEL name="dockerfile-dome" version="1.0" author="itcrazy2016"
COPY vitshop-0.0.1.jar vitshop.jar
CMD ["java","-jar","vitshop.jar"]
保存 Dockerfile 文件之后,使用 docker build -t vitshop-image 命令创建 image。
等待创建完毕之后就可以,运行或者查看 image 镜像了。
docker build -t vitshop-image . # -t vitshop-image 是自定义的名称
docker iamges # 查看所有的镜像
docker run -d --name vitshop -p 80:8080 vitshop-image # 运行自己创建的 image镜像
** 登陆阿里云控制台,找到容器镜像服务标签,选择下面的镜像仓库开通空间之后照下面命令上传自己的镜像。 **
# 登陆到阿里云镜像仓库
$ sudo docker login --username=tb4005142_00 registry.cn-beijing.aliyuncs.com
# 给自定的镜像打包
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/daozhuang/daozhuang:[镜像版本号]
# 推送到阿里云仓库
$ sudo docker push registry.cn-beijing.aliyuncs.com/daozhuang/daozhuang:[镜像版本号]
# 从Registry中拉取镜像
$ sudo docker pull registry.cn-beijing.aliyuncs.com/daozhuang/daozhuang:[镜像版本号]
# 从ECS推送镜像时,可以选择使用镜像仓库内网地址。推送速度将得到提升并且将不会损耗您的公网流量。
# 如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-beijing.aliyuncs.com 作为Registry的域名登录,并作为镜像命名空间前缀。
Docker commit 命令
docker commit :从容器创建一个新的镜像。
语法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker commit -a "xxxx" -m "xxxx" a404c6c174a2 mymysql:v1
OPTIONS说明:
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。
语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run --name mynginx -d nginx:latest
# 内存限制
docker run -d --memory 100M --name tomcat01 tomcat
# cpu限制 设置CPU权重
docker run -d --cpu-shares 10 --name tomcat01 tomcat
OPTIONS说明:
-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的高端口
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
–name=“nginx-lb”: 为容器指定一个名称;
–dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
–dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h “mars”: 指定容器的hostname;
-e username=“ritchie”: 设置环境变量;
–env-file=[]: 从指定文件读入环境变量;
–cpuset=“0-2” or --cpuset=“0,1,2”: 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
–net=“bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
–link=[]: 添加链接到另一个容器;
–expose=[]: 开放一个端口或一组端口;
–volume , -v: 绑定一个卷
docker默认网路 bridge
Docker启动的时候会在主机上自动创建一个docker0网桥,实际上是一个Linux网桥,所有容器的启动如果在docker run的时候没有指定网络模式的情况下都会挂载到docker0网桥上。这样容器就可以和主机甚至是其他容器之间通讯了。
我们可以使用 命令 ip a 查看所有的网卡
host模式网络
该模式中将禁用Docker容器的网络隔离,容器共享宿主机的网络命名空间,直接暴露在公网中,容器会继承宿主机的IP地址。使用host模式会将容器直接暴露在公网,会存在安全隐患。
container模式网络
该模式中,容器会使用另一个容器的网络命名空间。使用方式为:–net=container:containername
none模式网络
该模式将容器放置在自己的网络栈中,并不进行任何配置,该模式实际上是关闭了容器的网络功能。
外部访问容器:
外部要访问容器使用: -p 参数把容器端口映射到宿主机上即可访问,-p 和 -P是有区别的 -P是随机映射端口范围是 49000~49900;
-p是要自己指定端口号, 如:-p hostPort:containerPort
容器访问外部:
默认情况下,容器可以访问到外部网络的连接,因为容器的默认网络接口为docker0网桥上的接口,也即是主机上的本地接口。其原理是通过Linux系统的转发功能实现的,在Linux中检查转发是否打开:
[root@VM_0_14_centos ~]# sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
0表示转发未打开,1表示转发已经打开。可以在docker run时使用–ip-forward=true来指定,Docker会打开主机的转发功能。
同时可以通过上述的nat表中找到对应的规则,在POSTRONTING的第一个规则就是把所有原地址在172.17.0.0/16网段但不是属于Docker0的网包(即容器中的网包),动态伪装为0.0.0.0/0网段,即主机网卡。
docker默认的网络模式
在使用此网络模式的时候需要端口映射,
Docker网络操作:
# 创建网路
docker network create -d bridge --subnet 172.25.0.0/16 mynet
# 连接一个网络到容器中
docker network connect [OPTIONS] NETWORK CONTAINER
docker network connect mynet containername
# 查看所有网络
docker network ls
# 删除网络
docker network rm
# 容器和网络断开连接
docker network disconnect [OPTIONS] NETWORK CONTAINER
# 查看网络详情
docker network inspect
容器之间相互通讯可以通过docker run中的–link=container_name:alias参数来达到效果。
此种方式可以很方便让容器使用容器名进行通讯,而不需要依赖ip地址,不过link方式仅仅解决了单机容器间的互联,多机的情况下,需要通过别的方式进行连接。
Docker的镜像是由多个文件系统(只读)叠加而成,当我们启动一个容器的时候,Docker会加载只读镜像层并在其上添加一层’读写层’.如果运行中的容器需要了一个文件,那么并不会修改只读层的文件,只会把该文件复制到’读写层’然后对他修改,只读层的文件就被隐藏了,当删除了Docker容器之后,或者重启容器之后,之前对文件的更改会丢失,镜像的只读层以及容器运行时的’读写层’被称为Union File System(联合文件系统)
为了能够保存数据的持久化以及共享容器之间的数据,提出了Volume的概念。简单来说Volume就是一个文件或者目录。它可以绕过联合文件系统,以正常的文件或者目录的形式保存在主机上。可以通过两种方式来初始化Volume,这两种方式有一些细微区别。
运行时创建 volume
# 使用 -v 参数指定挂载的目录 声明volume
# 以下命令会创建一个CentOs的容器并且把容器内部的/data目录作为数据卷挂载
docker run -it --name centOs -v /data centos
# 查看挂载的volume,可以看到容器已经把/var/lob/docker/volumes/xxx/_data目录挂载到容器的/data目录了。
docker inspect -f {{.Mounts}} centOs
[{volume centOs /var/lib/docker/volumes/XXXXX/_data /data local true }]
# 该命令是将主机的/home/centos/data目录挂载到容器的/data目录。
docker run -it --name centOs -v /home/centos/data:/data centos
另外值得注意的是,只要将主机的目录挂载到容器上,那改变就会立即生效。挂载目录不会将镜像的文件复制到Volume中,只会把主机中不存在的文件夹创建出来。
数据共享
如果要授权一个容器访问另一个容器的Volume,可以使用-volumes-from参数来执行docker run命令:
docker run -it --name centOs1 --volumes-from centOs centos
不管容器是否正在运行,Volume都不会被删除。
如果使用数据卷容器,想做备份和恢复就非常容易了。假设有较多的镜像从centOs中挂载了数据卷,那么备份与恢复只需针对centOs这个容器即可。
备份
docker run --volumes-from centOs -v $(pwd):/backup --name worker centos tar cvf /backup/backup.tar /data
这个命令的意思是 将当前目录挂载到容器的/backup 目录,然后容器的工作就是压缩 /data的内容到 /back/backup.tar文件中。执行完之后就会看见在当前目录中生成了backup.tar文件
恢复
docker run --volumes-from centOs -v $(pwd):/backup centos tar xvf /backup/backup.tar -C /data
删除数据卷
Volume可以使用两种方式删除数据卷:
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。
运行以下命令以下载 Docker Compose 的当前稳定版本:要安装其他版本的 Compose,请替换 1.24.1。
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version
注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。
# 创建一个测试目录:
mkdir composetest
cd composetest
# 在此文件夹中放置 需要运行的项目 如: springboot.jar,还有Dockerfile,和docker-compose.yml
springboot.jar
Dockerfile
docker-compose.yml
docker-compose.yml 配置文件:
# yaml 配置
version: '3' # 指定本 yml 依从的 compose 哪个版本制定的。
services: #
web: # 该 web 服务使用从 Dockerfile 当前目录中构建的镜像。
build: . # 指定为构建镜像上下文路径:也就是Dockerfile文件的路径
networks: # 指定容器连接的网络,使用顶级 networks 下的条目 。
- app-net #
redis: #
image: "redis:alpine" # 指定容器运行的镜像。
networks: # 指定容器连接的网络,使用顶级 networks 下的条目 。
- app-net
networks: # 配置网络 如果没有会自动创建
app-net:
driver: bridge
使用 Compose 命令构建和运行您的应用:
# 在测试目录中,执行以下命令来启动应用程序:
docker-compose up
# 如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d
# 若要对容器进行扩缩容
docker-compose up --scale web=5 -d
docker-compose ps
docker-compose logs web
Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。
支持的工具包括但不限于以下各项: Dokku、Docker Compose、Docker Machine、Jenkins
如下图所示,swarm 集群由管理节点(manager)和工作节点(work node)构成。
docker swarm init --advertise-addr=192.168.0.11 # 这里的ip对应的是宿主机的ip
注意观察日志,拿到worker node加入manager node的信息
2. 进入两个worker 执行以下命令,加入到manager 集群中
docker swarm join --token SWMTKN-1-3zzim2k6p9v18ed2l94li2dngt10kvkibfa94gpjqvlt280y0f-9gkawx7564dzh4fvmqccwhnyh 192.168.0.48:2377
# 日志打印
This node joined a swarm as a worker.
# 进入到 manager node 查看所有node节点
docker node ls
# 将 worker node 升级为 manager
docker node promote NODENAME
# 将 manager node 降级为 worker
docker node demote NODENAME
# 停止某个节点
docker node update --availability drain swarm-worker1
# 从新启动某个节点
docker node update --availability active swarm-worker1
注意:swarm-worker1 状态变为 Drain。不会影响到集群的服务,只是 swarm-worker1 节点不再接收新的任务,集群的负载能力有所下降。
# 创建一个tomcat的service
docker service create --name my-tomcat tomcat
# 查看当前swarm的service
docker service ls
# 查看service的启动日志
docker service logs my-tomcat
# 查看 service详情
docker service inspect my-tomcat
# 查看 my-tomcat 运行在哪个node上
docker service ps my-tomcat
# 水平扩展service
docker service scale my-tomcat=5
# 查看所有service
docker service ls
# 删除 service
docker service rm my-tomcat
参考文章 https://blog.csdn.net/u012943767/article/details/79767670