Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。 docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。 1.不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。 2.你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。 3.在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。 总之docker就是集装箱原理。
Docker在开发与运维的世界中具有极大的吸引力,因为它能保持跨环境的一致性。在开发与发布的生命周期中,不同的环境具有细微的不同,这些差异可能是由于不同安装包的版本和依赖关系引起的。然而,Docker可以通过确保从开发到产品发布整个过程环境的一致性来解决这个问题。 Docker容器通过相关配置,保持容器内部所有的配置和依赖关系始终不变。最终,你可以在开发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。 使用Docker,你还可以确保开发者不需要配置完全相同的产品环境,他们可以在他们自己的系统上通过VirtualBox建立虚拟机来运行Docker容器。Docker的魅力在于它同样可以让你在亚马逊EC2实例上运行相同的容器。如果你需要在一个产品发布周期中完成一次升级,你可以很容易地将需要变更的东西放到Docker容器中,测试它们,并且使你已经存在的容器执行相同的变更。这种灵活性就是使用Docker的一个主要好处。和标准部署与集成过程一样,Docker可以让你构建、测试和发布镜像,这个镜像可以跨多个服务器进行部署。哪怕安装一个新的安全补丁,整个过程也是一样的。你可以安装补丁,然后测试它,并且将这个补丁发布到产品中。
Docker容器可以在不同的开发与产品发布生命周期中确保一致性,进而标准化你的环境。除此之外,Docker容器还可以像git仓库一样,可以让你提交变更到Docker镜像中并通过不同的版本来管理它们。设想如果你因为完成了一个组件的升级而导致你整个环境都损坏了,Docker可以让你轻松地回滚到这个镜像的前一个版本。这整个过程可以在几分钟内完成,如果和虚拟机的备份或者镜像创建流程对比,那Docker算相当快的,它可以让你快速地进行复制和实现冗余。此外,启动Docker就和运行一个进程一样快。
Docker可以确保你的应用程序与资源是分隔开的。几个月前,Gartner发表了一篇报告,这份报告说明了运行Docker 容器进行资源隔离的效果和虚拟机(VM)管理程序一样的好,但是管理与控制方面还需要进行完善。我们考虑这样一个场景,你在你的虚拟机中运行了很多应用程序,这些应用程序包括团队协作软件(例如Confluence)、问题追踪软件(例如JIRA)、集中身份管理系统(例如Crowd)等等。由于这些软件运行在不同的端口上,所以你必须使用Apache或者Nginx来做反向代理。到目前为止,一切都很正常,但是随着你的环境向前推进,你需要在你现有的环境中配置一个内容管理系统(例如Alfresco)。这时候有个问题发生了,这个软件需要一个不同版本的Apache Tomcat,为了满足这个需求,你只能将你现有的软件迁移到另一个版本的Tomcat上,或者找到适合你现有Tomcat的内容管理系统(Alfresco)版本。对于上述场景,使用Docker就不用做这些事情了。Docker能够确保每个容器都拥有自己的资源,并且和其他容器是隔离的。你可以用不同的容器来运行使用不同堆栈的应用程序。除此之外,如果你想在服务器上直接删除一些应用程序是比较困难的,因为这样可能引发依赖关系冲突。而Docker可以帮你确保应用程序被完全清除,因为不同的应用程序运行在不同的容器上,如果你不在需要一款应用程序,那你可以简单地通过删除容器来删除这个应用程序,并且在你的宿主机操作系统上不会留下任何的临时文件或者配置文件。除了上述好处,Docker还能确保每个应用程序只使用分配给它的资源(包括CPU、内存和磁盘空间)。一个特殊的软件将不会使用你全部的可用资源,要不然这将导致性能降低,甚至让其他应用程序完全停止工作。
如上所述,Gartner也承认Docker正在快速地发展。从安全角度来看,Docker确保运行在容器中的应用程序和其他容器中的应用程序是完全分隔与隔离的,在通信流量和管理上赋予你完全的控制权。Docker容器不能窥视运行在其他容器中的进程。从体系结构角度来看,每个容器只使用着自己的资源(从进程到网络堆栈)。作为紧固安全的一种手段,Docker将宿主机操作系统上的敏感挂载点(例如/proc和/sys)作为只读挂载点,并且使用一种写时复制系统来确保容器不能读取其他容器的数据。Docker也限制了宿主机操作系统上的一些系统调用,并且和SELinux与AppArmor一起运行的很好。此外,在Docker Hub上可以使用的Docker镜像都通过数字签名来确保其可靠性。由于Docker容器是隔离的,并且资源是受限制的,所以即使你其中一个应用程序被黑,也不会影响运行在其它Docker容器上的应用程序。
Docker最大的好处之一就是可移植性。在过去的几年里,所有主流的云计算提供商,包括亚马逊AWS和谷歌的GCP,都将Docker融入到他们的平台并增加了各自的支持。Docker容器能运行在亚马逊的EC2实例、谷歌的GCP实例、Rackspace服务器或者VirtualBox这些提供主机操作系统的平台上。举例来说,如果运行在亚马逊EC2实例上的Docker容器能够很容易地移植到其他几个平台上,比如说VirtualBox,并且达到类似的一致性和功能性,那这将允许你从基础设施层中抽象出来。除了AWS和GCP,Docker在其他不同的IaaS提供商也运行的非常好,例如微软的Azure、OpenStack和可以被具有不同配置的管理者所使用的Chef、Puppet、Ansible等。
Docker Enterprise Edition (Docker EE) is designed for enterprise development and IT teams who build, ship, and run business critical applications in production at scale. Docker EE is integrated, certified, and supported to provide enterprises with the most secure container platform in the industry to modernize all applications. For more information about Docker EE, including purchasing options, see Docker Enterprise Edition. Docker Community Edition (Docker CE) is ideal for developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker CE is available on many platforms, from desktop to cloud to server. Docker CE is available for macOS and Windows and provides a native experience to help you focus on learning Docker. You can build and share containers and automate the development pipeline all from a single environment. Docker CE has both stable and edge channels. Stable builds are released once per quarter and are supported for 4 months. Edge builds are released once per month, and are supported for that month only. If you subscribe to the Edge channel on Linux distributions, you should also subscribe to the Stable channel.
官网总的安装手册:https://docs.docker.com/install/
官网 CentOS 安装手册:https://docs.docker.com/install/linux/docker-ce/centos/
目前也支持 Windows,特别是 Windows 10,直接官网一个安装包即可搞定。
Windows 10 的 Docker 安装说明:https://store.docker.com/editions/community/docker-ce-desktop-windows
我这里选择 Docker CE 版本:
CentOS 安装过程:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum makecache fast
sudo yum install -y docker-ce
,大小:19M,速度很慢。查看配置文件位置:systemctl show --property=FragmentPath docker
启动 Docker:systemctl start docker.service
停止 Docker:systemctl stop docker.service
查看状态:systemctl status docker.service
运行 hello world 镜像:sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
https://ldhc17y9.mirror.aliyuncs.com
,所以下面文章你看到该地址都表示是这个专属地址,请记得自己更换自己的。vim /etc/docker/daemon.json
,增加如下内容:{
"registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
namespace管理
中创建属于你自己的 namespace:https://cr.console.aliyun.com/#/namespace/index
管理
进入查看仓库的更多详细信息,这里面有很多有用的信息,包括一个详细的操作指南,这份指南等下会用到。
registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster
docker login registry.cn-shenzhen.aliyuncs.com
会让我输入
Username:阿里云邮箱
password:上文提到的--Registry登录密码
docker pull registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号]
docker login
docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号]
docker push registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号]
http://192.168.137.128
systemctl stop firewalld.service ; systemctl stop iptables.service
systemctl restart docker.service
/opt/setups
http://127.0.0.1:8080/youmeek
docker pull centos:6.8
,我的 IMAGE_ID 为:0cd976dc0a98
docker run -i -t -v /opt/setups:/opt 0cd976dc0a98 /bin/bash
-v:表示需要将本地宿主机的目录挂载到容器中对应的一个目录上,格式:-v <宿主机目录>:<容器目录>,所以此时对容器此目录的操作,也是等同于对宿主机的目录的操作
cp /opt/spring-boot-my-demo.jar /root
vi /root/spring-boot-run.sh
,脚本内容如下:#!/bin/bash
source /etc/profile
java -jar /root/spring-boot-my-demo.jar
chmod u+x /root/spring-boot-run.sh
docker ps -a
a5d544d9b6f9
,这个下面要用到docker commit a5d544d9b6f9 youmeek/springboot:0.1
docker images
,会发现多了一个 youmeek/springboot 新镜像,镜像 ID 为:7024f230fef9
docker run -d -p 38080:8080 --name=springBootJar --hostname=springBootJar 7024f230fef9 /root/spring-boot-run.sh
-d
:表示以“守护模式”执行 spring-boot-run.sh 脚本,此时 jar 中的 log 日志不会出现在输出终端上。 -p
:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 38080 端口,这样就向外界暴露了 38080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。 --name
:表示给新实例容器取的名称,用一个有意义的名称命名即可docker ps -a
,可以知道我们的新容器 ID:fd21ac056343
,名称为:springBootJar
docker logs -f fd21ac056343
,可以看到 jar 启动后的 log 输出内容http://192.168.137.128:38080/youmeek/
,可以看到 jar 应用的首页可以访问docker version
,查看docker版本docker info
,显示docker系统的信息docker pull
:从仓库下载镜像到本地docker pull centos:latest
:获取 CentOS 默认版本镜像docker pull centos:7.3.1611
:获取 CentOS 7 镜像,下载大小 70M 左右,下面的操作基于此镜像docker pull centos:6.8
:获取 CentOS 6 镜像docker pull registry.cn-hangzhou.aliyuncs.com/chainone/centos7-jdk8
:获取别人做好的阿里云镜像docker push
:将一个镜像 push 到 registry 仓库中docker push myapache:v1
docker search
:从 registry 仓库搜索镜像docker search -s 3 centos
,参数 -s 数字
:表示筛选出收藏数(stars值)大于等于 3 的镜像docker login
:登录到一个镜像仓库。默认登录的是官网的仓库:https://hub.docker.comsudo docker login --username=阿里云邮箱
docker login --username=23333212@qq.com registry.cn-shenzhen.aliyuncs.com
,你完整的登录地址你需要访问:https://cr.console.aliyun.com/#/imageList,在你自己创建的仓库中去查看那份详细操作指南上的地址docker stats
:查看当前启动的容器各自占用的系统资源bin docker stats --no-stream kafkadocker_kafka_1 kafkadocker_zookeeper_1
:查看指定容器的占用资源情况CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
4532a9ee27b8 cloud-cadvisor 1.49% 53.28MiB / 3.702GiB 1.41% 13.5MB / 646MB 265MB / 0B 19
3895d5d50a5e kafkadocker_kafka_1 1.45% 1.24GiB / 3.702GiB 33.51% 145MB / 186MB 499MB / 724MB 128
1d1a6a7c48d8 kafkadocker_zookeeper_1 0.11% 70.85MiB / 3.702GiB 1.87% 55.8MB / 33.7MB 209MB / 1.22MB 23
docker images
:显示本地所有的镜像列表docker images centos
:查看具体镜像情况docker rmi
:删除镜像,一般删除镜像前要先删除容器,不然如果镜像有被容器调用会报错docker rmi 容器ID
:删除具体某一个镜像docker rmi 仓库:Tag
:删除具体某一个镜像docker rmi $(docker images -q)
,删除所有镜像docker rmi -f $(docker images -q)
,强制删除所有镜像docker rmi $(docker images | grep "vmware" | awk '{print $3}')
,批量删除带有 vmware 名称的镜像docker tag
:为镜像打上标签docker tag -f ubuntu:14.04 ubuntu:latest
,-f 意思是强制覆盖docker rmi 仓库:Tag
,取消标签(如果是镜像的最后一个标签,则会删除这个镜像)docker build
:使用 Dockerfile 创建镜像(推荐)docker build . --rm -t runoob/ubuntu:v1
,参数 -t
,表示:-tag,打标签docker build --no-cache . --rm -t runoob/ubuntu:v1
docker history
:显示生成一个镜像的历史命令,可以看出这个镜像的构建过程,包括:每一层镜像的 ID、指令docker save
:将一个镜像保存为一个 tar 包,带 layers 和 tag 信息(导出一个镜像)docker save 镜像ID -o /opt/test.tar
docker load
:从一个 tar 包创建一个镜像(导入一个镜像)docker load -i /opt/test.tar
docker run
,运行镜像docker run -v /java_logs/:/opt/ -d -p 8080:80 --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t 镜像ID /bin/bash
-i -t
分别表示保证容器中的 STDIN 开启,并分配一个伪 tty 终端进行交互,这两个是合着用。--name
是给容器起了一个名字(如果没有主动给名字,docker 会自动给你生成一个)容器的名称规则:大小写字母、数字、下划线、圆点、中横线,用正则表达式来表达就是:[a-zA-Z0-9_*-]-d
容器运行在后台。-p 8080:80
表示端口映射,将宿主机的8080端口转发到容器内的80端口。(如果是 -P 参数,则表示随机映射应该端口,一般用在测试的时候)-v /java_logs/:/opt/
表示目录挂载,/java_logs/ 是宿主机的目录,/opt/ 是容器目录docker run --rm --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t centos /bin/bash
,--rm,表示退出即删除容器,一般用在做实验测试的时候docker run --restart=always -i -t centos /bin/bash
,--restart=always 表示停止后会自动重启docker run --restart=on-failure:5 -i -t centos /bin/bash
,--restart=on-failure:5 表示停止后会自动重启,最多重启 5 次docker exec
:对守护式的容器里面执行命令,方便对正在运行的容器进行维护、监控、管理docker exec -i -t 容器ID /bin/bash
,进入正在运行的 docker 容器,并启动终端交互docker exec -d 容器ID touch /opt/test.txt
,已守护式的方式进入 docker 容器,并创建一个文件docker stop 容器ID
,停止容器docker stop $(docker ps -a -q)
,停止所有容器docker stop $(docker ps -a -q) ; docker rm $(docker ps -a -q)
,停止所有容器,并删除所有容器docker kill $(docker ps -q) ; docker rm $(docker ps -a -q)
,停止所有容器,并删除所有容器docker start 容器ID
,重新启动已经停止的容器(重新启动,docker run 参数还是保留之前的)docker restart 容器ID
,重启容器docker rm
,删除容器docker rm 容器ID
,删除指定容器(该容器必须是停止的)docker rm -f 容器ID
,删除指定容器(该容器如果正在运行可以这样删除)docker rm $(docker ps -a -q)
,删除所有容器docker rm -f $(docker ps -a -q)
,强制删除所有容器docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
删除老的(一周前创建)容器docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a)
停止所有容器,删除所有容器,删除所有镜像docker commit
,把容器打成镜像docker commit 容器ID gitnavi/docker-nodejs-test:0.1
docker commit -m="这是一个描述信息" --author="GitNavi" 容器ID gitnavi/docker-nodejs-test:0.1
docker diff 容器ID
:显示容器文件系统的前后变化--link
同一个宿主机下的不同容器的连接:docker run -it 镜像ID --link redis-name:myredis /bin/bash
redis-name
是容器名称myredis
是容器别名,其他容器连接它可以用这个别名来写入到自己的配置文件中docker cp /www/runoob 96f7f14e99ab:/www/
将主机 /www/runoob 目录拷贝到容器 96f7f14e99ab 的 /www 目录下docker cp /www/runoob 96f7f14e99ab:/www
将主机 /www/runoob 目录拷贝到容器 96f7f14e99ab 中,目录重命名为 www。docker cp 96f7f14e99ab:/www /tmp/
将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。docker network ls
docker network create --subnet=172.19.0.0/16 net-redis-to-cluster
docker network connect net-redis-to-cluster my-redis-container
--network XXXXXX
常见几种模式docker run -it 镜像ID --network=bridge /bin/bash
docker run -it 镜像ID --network=none /bin/bash
docker run -it 镜像ID --network=host /bin/bash
docker run -it 镜像ID --network=自定义名称 /bin/bash
docker ps
:列出当前所有 正在运行 的容器docker ps -a
:列出所有的容器(包含历史,即运行过的容器)docker ps -l
:列出最近一次启动的containerdocker ps -q
:列出最近一次运行的container IDdocker ps -a -l
:列出最后一次运行的容器docker ps -n x
:显示最后 x 个容器,不管是正在运行或是已经停止的docker top 容器ID
:显示容器的进程信息docker events
:得到 docker 服务器的实时的事件docker logs -f 容器ID
:查看容器日志(如果一些容器不断重启,或是自动停止,可以这样看下)docker logs 容器ID
,获取守护式容器的日志docker logs -f 容器ID
,不断监控容器日志,类似 tail -fdocker logs -ft 容器ID
,在 -f 的基础上又增加 -t 表示为每条日志加上时间戳,方便调试docker logs --tail 10 容器ID
,获取日志最后 10 行docker logs --tail 0 -f 容器ID
,跟踪某个容器的最新日志而不必读取日志文件docker logs -f -t --since="2018-05-26" --tail=200 容器ID
根据某个时间读取日志docker logs -f -t --since="2018-05-26T11:13:40" --tail=200 容器ID
根据某个时间读取日志docker logs -f -t --since="2018-05-25T11:13:40" --until "2018-05-26T11:13:40" --tail=200 容器ID
根据某个时间读取日志docker logs --since 10m 容器ID
查看最近 10 分钟的日志-f
: 表示查看实时日志 -t
: 显示时间戳-since
: 显示某个开始时间的所有日志-tail=200
: 查看最后的 200 条日志docker wait
,阻塞到一个容器,直到容器停止运行docker export
,将容器整个文件系统导出为一个tar包,不带layers、tag等信息docker port
,显示容器的端口映射docker inspect 容器ID
:查看容器的全面信息,用 JSON 格式输出docker inspect network名称
:查看 network 信息,用 JSON 格式输出,包含使用该网络的容器有哪些docker system df
:类似于 Linux 上的 df 命令,用于查看 Docker 的磁盘使用情况TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 6 6 1.049GB 0B (0%)
Containers 7 4 10.25kB 0B (0%)
Local Volumes 13 5 38.49GB 1.365MB (0%)
Build Cache 0B 0B
获取容器中的 IP:docker inspect -f {{.NetworkSettings.IPAddress}} 容器ID
获取容器中的 IP:docker inspect -f {{.Volumes}} 容器ID
查看容器的挂载情况:docker inspect 容器ID | grep Mounts -A 10
[
{
"Id": "e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b",
"Created": "2018-01-18T03:47:16.138180181Z",
"Path": "docker-entrypoint.sh",
"Args": [
"--auth"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 19952,
"ExitCode": 0,
"Error": "",
"StartedAt": "2018-01-18T03:47:16.348568927Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:42aa46cfbd7a0d1101311defac39872b447b32295b40f9c99104ede5d02e9677",
"ResolvConfPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hostname",
"HostsPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hosts",
"LogPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b-json.log",
"Name": "/cas-mongo",
"RestartCount": 0,
"Driver": "overlay",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/data/mongo/db:/data/db"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"27017/tcp": [
{
"HostIp": "",
"HostPort": "27017"
}
]
},
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay/0ab08b1f9c8f5f70cdcac2b01d9ee31de9e5a4955003567573635e8837931249/root",
"MergedDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/merged",
"UpperDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/upper",
"WorkDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/work"
},
"Name": "overlay"
},
"Mounts": [
{
"Type": "volume",
"Name": "6cd9721ff6a2768cd20e4a0678b176fa81a5de1c7d21fe6212b50c6854196db2",
"Source": "/var/lib/docker/volumes/6cd9721ff6a2768cd20e4a0678b176fa81a5de1c7d21fe6212b50c6854196db2/_data",
"Destination": "/data/configdb",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "bind",
"Source": "/data/mongo/db",
"Destination": "/data/db",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "e1dff77b99d9",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"27017/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.7",
"GPG_KEYS=0C49F3730359A14518585931BC711F9BA15703C6",
"MONGO_PACKAGE=mongodb-org",
"MONGO_REPO=repo.mongodb.org",
"MONGO_MAJOR=3.4",
"MONGO_VERSION=3.4.10"
],
"Cmd": [
"--auth"
],
"Image": "mongo:3.4",
"Volumes": {
"/data/configdb": {},
"/data/db": {}
},
"WorkingDir": "",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "7eabf418238f4d9f5fd5163fd4d173bbaea7764687a5cf40a9757d42b90ab2f9",
"HairpinMode": false,
"Link LocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"27017/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "27017"
}
]
},
"SandboxKey": "/var/run/docker/netns/7eabf418238f",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "11c8d10a4be63b4ed710add6c440adf9d090b71918d4aaa837c46258e5425b80",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "ada97659acda146fc57e15a099e430a6e97de87f6d043b91d4c3582f6ab52d47",
"EndpointID": "11c8d10a4be63b4ed710add6c440adf9d090b71918d4aaa837c46258e5425b80",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
/var/lib/docker/containers/容器ID值/容器ID值-json.log
echo > 容器ID值-json.log
vim /etc/docker/daemon.json
,(如果没有这个文件,自己新增)增加如下内容:{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}
{
"registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}
docker rmi $(docker images -f "dangling=true" -q)
192.168.1.22
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376
ExecStart=/usr/bin/dockerd --insecure-registry harbor.youmeek.com -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376
systemctl daemon-reload
systemctl reload docker
systemctl restart docker
docker -H 192.168.1.22:2376 images
# 这是一段注释说明
FROM
,基础镜像信息MAINTAINER
,维护者/创建者信息ADD
,添加文件。如果添加的文件是类似 tar.gz 压缩包,会自动解压。ADD test.tar.gz /opt/shell/
。不是斜杠结尾会认为是文件。ADD test.sh /opt/shell/test.sh
ADD test.tar.gz /opt/shell/
,该压缩包会自动解压在 /opt/shell 目录下COPY
,类似 ADD,只是 COPY 只是复制文件,不会做类似解压压缩包这种行为。COPY /opt/conf/ /etc/
把宿主机的 /opt/conf 下文件复制到镜像的 /etc 目录下。WORKDIR
,设置工作目录,可以理解为类似 cd 命令,表示现在在某个目录路径,然后下面的 CMD、ENTRYPOINT 操作都是基于此目录VOLUME
,目录挂载EXPOSE
,暴露端口USER
,指定该镜像以什么用户去运行,也可以用这个来指定:docker run -u root
。不指定默认是 rootENV
,定义环境变量,该变量可以在后续的任何 RUN 指令中使用,使用方式:$HOME_DIR。在 docker run 的时候可以该方式来覆盖变量值 docker run -e “HOME_DIR=/opt”
RUN
,执行命令并创建新的镜像层,RUN 经常用于安装软件包CMD
,执行命令,并且一个 Dockerfile 只能有一条 CMD,有多条的情况下最后一条有效。在一种场景下 CMD 命令无效:docker run 的时候也指定了相同命令,则 docker run 命令优先级最高ENTRYPOINT
,配置容器启动时运行的命令,不会被 docker run 指令覆盖,并且 docker run 的指令可以作为参数传递到 ENTRYPOINT 中。要覆盖 ENTRYPOINT 命令也是有办法的:docker run --entrypoint 方式。Dockerfile 同时有 CMD 和 ENTRYPOINT 的时候,CMD 的指令是作为参数传递给 ENTRYPOINT 使用。FROM java:8-jre
MAINTAINER gitnavi <gitnavi@qq.com>
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD skb-user-0.0.1-SNAPSHOT.jar /usr/local/skb/user/
CMD ["java", "-Xmx500m", "-jar", "/usr/local/skb/user/skb-user-0.0.1-SNAPSHOT.jar", "--spring.profiles.active=test"]
EXPOSE 9096
cd /opt/zch
docker build . --tag="skb/user:v1.0.1"
docker run -d -p 9096:9096 -v /usr/local/logs/:/opt/ --name=skbUser --hostname=skbUser skb/user:v1.0.1
docker ps
firewall-cmd --zone=public --add-port=9096/tcp --permanent
firewall-cmd --reload
# 是为了解决容器的时区和宿主机不一致问题
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
FROM tomcat:8.0.46-jre8
MAINTAINER GitNavi <gitnavi@qq.com>
ENV JAVA_OPTS="-Xms2g -Xmx2g -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=312M"
ENV CATALINA_HOME /usr/local/tomcat
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN rm -rf /usr/local/tomcat/webapps/*
ADD qiyeweixin.war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["catalina.sh", "run"]
docker build -t harbor.gitnavi.com/demo/qiyeweixin:1.2.2 ./
docker run -d -p 8888:8080 --name=qiyeweixin --hostname=qiyeweixin -v /data/docker/logs/qiyeweixin:/data/logs/qiyeweixin harbor.gitnavi.com/demo/qiyeweixin:1.2.2
docker run -d -p 8888:8080 -e JAVA_OPTS='-Xms7g -Xmx7g -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M' --name=qiyeweixin --hostname=qiyeweixin -v /data/docker/logs/qiyeweixin:/data/logs/qiyeweixin harbor.gitnavi.com/demo/qiyeweixin:1.2.2
long maxMemory = Runtime.getRuntime().maxMemory();
logger.warn("-------------maxMemory=" + ((double) maxMemory / (1024 * 1024)));
docker-compose up
docker-compose -f zookeeper.yml -p zk_test up -d
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
,输出:docker-compose version 1.18.0, build 8dd22a9
docker-compose up -d
docker-compose down
docker-compose ps
docker-compose rm