Docker 是一个开源的容器引擎,能够轻松的为任何应用建立一个轻量级的、可移植的、自给自足的容器。开发者和系统管理员在笔记本上编译测试经过的容器能够批量地在生产环境中部署,包括 VMs(虚拟机)、bare metal、OpenStack 集群、云端、数据中心和其余的基础应用平台。容器是彻底使用沙箱机制,相互之间不会有任何接口。php
为啥要用Docker?这要从目前软件行业的痛点来说起html
有了Docker能够很大程度解决上面的问题。java
首先,Docker的使用简单至极,从开发的角度来看就是三步走:构建,运输,运行。其中关键步骤就是构建环节,即打包镜像文件。可是从测试和运维的角度来看,那就只有两步:复制,运行。有了这个镜像,那么想复制到哪运行均可以,彻底和平台无关了。同时Docker这种容器技术隔离出了独立的运行空间,不会和其余应用争用系统资源了以及还不须要考虑应用之间相互影响,想一想就开心。node
其次,由于在构建镜像的时候就处理完了服务程序对于系统的全部依赖,因此在你使用的时候,你能够忽略掉本来程序的依赖以及开发语言。对测试和运维而言,更多专一于本身的业务内容上。python
最后,Docker于开发者而言提供了一种开发环境的管理办法,与测试人员而言保证了环境的同步,于运维人员提供了可移植的标准化部署流程。linux
你须要在本地系统快速尝试 Magento,或者为一个项目使用 MySQL?仍是但愿尝试大部分开源项目?那就使用 Docker 吧,它将帮你节省大量时间。Docker 能提高开发者的开发效率,让咱们快速搭建开发环境。nginx
开发环境的机器一般内存比较小,此前使用虚拟的时候,常常须要为开发环境的机器加内存,而经过 Docker 能够轻易的让几十个服务在 Docker 中跑起来。git
若是你但愿构建源码,但发现没有准备好合适的环境。github
那么使用 Docker是一个值得考虑的方案。毕竟若是使用传统的方法一个一个地安装软件,一大堆软件安装下来确实十分费时间,使用容器技术省时省力,何乐而不为?它能让你将运行环境和配置放在代码中而后部署,同一个 Docker 的配置能够在不一样的环境中使用,这样就下降了硬件要求和应用环境之间耦合度。这里有一个值得一看的例子: docker golang builder。golang
你在使用微服务吗?微服务架构将一个总体式的应用拆分红松耦合的单个服务。
那不妨考虑一下 Docker,你能够将每一个服务打包为一个docker镜像并使用docker-compose 来模拟生产环境(checkout docker networks)。最开始实践的时候可能会比较费时费力,但长远地来看,最终将产生巨大的生产力。
试想这样一个问题,如何编写自动化的集成测试用例,这些测试用例无需花很长时间来开始运行,使用者也可轻松管理。这里不是指在 Docker 中运行测试用例,而是将测试用例与镜像紧密运行在一块儿。当你针对一个 docker 镜像编写测试用例时会有一个很大的优点。下面简单介绍一下个人测试流程:运行两个 docker 镜像(app + db),在 MySQL 启动时加载数据,并在 app docker 上使用 API。可查看此脚本以获取快速的示例。
你可使用 docker 镜像进行自我部署。许多主流的主机提供商都支持托管 docker,若是你拥有一个具备 shell 访问权限的专用节点/vm,那么事情将变得更容易。只须要设置好docker,并在你想要的端口上运行你的镜像便可。
都说 Docker 天生适合持续集成/持续部署,在部署中使用Docker,持续部署将变得很是简单,并会在进入新的镜像后从新开始。关于这个部分的自动化工做,如今已经有许多方案以供选择,Kubernetes就是一个耳熟能详的名字。Kubernetes是容器集群管理系统,是一个开源的平台,能够实现容器集群的自动化部署、自动扩缩容、维护等功能。
Docker 有意思的一个使用场景是在多租户的应用中,它能够避免关键应用的重写。若是你将应用程序服务公开给多个租户(租户指一组用户,例如组织),使用单租户方案设计的应用程序若是用上了 sub-domain + docker 能够快速得到提供多租户的服务。 关于这个场景的一个例子是为物联网的应用开发一个快速、易用的多租户环境。这种多租户的基本代码很是复杂,很难处理,从新规划这样一个应用不但消耗时间,也浪费金钱。使用Docker,能够为每个租户的应用层的多个实例建立隔离的环境,这不只简单并且成本低廉,固然这一切得益于 Docker 环境的启动速度和其高效的 diff 命令。
这与上面提到的微服务有些联系,但即便你没有使用微服务,只是提供服务,Docker仍能够很好地管理单个机器上的全部服务。你应该使用文件夹挂载来为每一个基于数据的 docker 镜像保留数据。
Docker 经过建立另外一个容器来帮助你轻松地进行水平扩展。若是遇到巨大的高峰流量,Docker能够帮助你解决问题 —— 只需添加更多的机器并增长负载均衡器背后运行的容器数量。
想全面了解的朋友能够参考:太全了|万字详解Docker架构原理、功能及使用
root@centos7 ~]# yum install docker -y
[root@centos7 ~]# systemctl start docker
复制代码
下载镜像文件
[root@centos7 ~]# docker pull centos:latest
Trying to pull repository docker.io/library/centos ...
centos7: Pulling from docker.io/library/centos
93857f76ae30: Pull complete
Digest: sha256:4eda692c08e0a065ae91d74e82fff4af3da307b4341ad61fa61771cc4659af60
[root@centos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos centos7 a8493f5f50ff 3 days ago 192.5 MB
复制代码
删除镜像
[root@centos7 ~]# docker rmi a8493f5f50ff ##容器ID
复制代码
方法一:
[root@centos7 ~]# docker run centos /bin/echo "nihao" ##建立容器
nihao
[root@centos7 ~]# docker ps -a ##查看全部容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3c113f9a4f1b centos "/bin/echo nihao" 43 seconds ago Exited (0) 41 seconds ago boring_liskov
复制代码
这里没有指定容器名称,自动命名,状态是自动退出
方法二:建立一个自定义名称的容器
[root@centos7 ~]# docker run --name mgg -t -i centos /bin/bash
名称 分配伪终端 -i 处于打开状态
[root@2db7f1389dbd /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 22:46 ? 00:00:00 /bin/bash
root 13 1 0 22:49 ? 00:00:00 ps -ef
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2db7f1389dbd centos "/bin/bash" 4 minutes ago Up 4 minutes mgg
复制代码
docker ps -a是显示全部容器包括没有运行的(同virsh list --all)
[root@2db7f1389dbd /]# exit ##退出容器
exit
[root@centos7 ~]# docker start 2db7f1389dbd ##启动容器
2db7f1389dbd
[root@centos7 ~]# docker attach 2db7f1389dbd ##进入容器(必须是启动状态下)
[root@2db7f1389dbd /]# hostname
2db7f1389dbd
复制代码
这种进入方式,退出后容器就进入Down状态,以下
[root@2db7f1389dbd /]# exit
exit
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
复制代码
[root@centos7 ~]# nsenter --help
Usage:
nsenter [options] <program> [<argument>...]
Run a program with namespaces of other processes.
Options:
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork do not fork before exec'ing <program>
-Z, --follow-context set SELinux context according to --target PID
-h, --help display this help and exit
-V, --version output version information and exit
复制代码
获取容器的PID
[root@centos7 ~]# docker inspect --format "{{.State.Pid}}" 2db7f1389dbd
4580
[root@centos7 ~]# nsenter -t 4580 -u -i -n -p
[root@2db7f1389dbd ~]# hostname
2db7f1389dbd
[root@2db7f1389dbd ~]# exit
logout
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2db7f1389dbd centos "/bin/bash" 22 minutes ago Up 7 minutes mgg
复制代码
[root@centos7 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2db7f1389dbd centos "/bin/bash" 31 minutes ago Up 16 minutes mgg
3c113f9a4f1b centos "/bin/echo nihao" 38 minutes ago Exited (0) 38 minutes ago boring_liskov
[root@centos7 ~]# docker rm 3c113f9a4f1b ##接名称也能够,删除一个中止的容器
3c113f9a4f1b
[root@centos7 ~]# docker rm -f 3c113f9a4f1b ##删除一个正在运行的容器
[root@centos7 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2db7f1389dbd centos "/bin/bash" 31 minutes ago Up 16 minutes mgg
[root@centos7 ~]# docker run --rm centos /bin/echo "hello" ##建立时自动删除,用于测试
[root@centos7 ~]#docker --kill $(docker ps -a -q) ##删除正在运行的容器
复制代码
Dokcer 经过使用 Linux 桥接提供容器之间的通讯,Docker的网络模式有四种
分别是如下四种模式:
host 模式,使用--net=host 指定。
container 模式,使用--net=container:NAMEorID 指定。
none 模式,使用--net=none 指定。
bridge 模式,使用--net=bridge 指定,默认配置
host 模式
若是容器使用 host 模式,那么容器将不会得到一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出本身的网卡与配置 IP 等,而是使用宿主机的 IP 和端口。就和直接跑在宿主机中同样。可是容器的文件系统、进程列表等仍是和宿主机隔离的。
这个模式指定新建立的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新建立的容器不会建立本身的网卡与配置 IP,而是和一个指定的容器共享 IP、端口范围等。一样,两个容器除了网络方面,其余方面仍然是隔离的。
此模式不一样于前两种,Docker 容器有本身的 Network Namespace,可是,Docker容器没有任何网络配置。而是须要咱们手动给 Docker容器添加网卡、配置 IP 等。
此模式是Docker默认的网络设置,此模式会为每个容器分配Network Namespace,并将一个主机上的Docker容器链接到一个虚拟网桥上。
更多关于Docker容器网络介绍请参考:Docker容器网络-基础篇,Docker容器网络-实现篇。
docker管理数据的方式有两种:
默认容器的数据是保存在容器的可读写层,当容器被删除时其上的数据也会丢失,因此为了实现数据的持久性则须要选择一种数据持久技术来保存数据。官方提供了三种存储方式:Volumes、Bind mounts和tmpfs。
从如今开始,咱们学习 Docker 容器的数据存储方式,你也能够先了解一下Docker 数据持久化的三种方案。
Bind mount 会覆盖容器中的文件,而 volume mount 则不会。即若是容器中已有文件,则会将文件同步到主机的目录上。此方式与 Linux 系统的 mount 方式很类似,便是会覆盖容器内已存在的目录或文件,但并不会改变容器内原有的文件,当 umount 后容器内原有的文件就会还原。
由docker建立和管理,且与主机的核心功能隔离
不管是命名仍是匿名数据卷,都存储在/var/lib/docker/volumes/下面
定义的数据卷能够在多个容器中同时使用,且不会自动删除
容许容器将内容保存到远端、云服务提供商、加密内容等等
数据卷是存储在 Docker 容器的特定目录下面
Docker Volumes 机制一般用来给 Docker 容器保存持久化数据,使用 Volumes 有不少优点:
Volumes 一般也优于容器的可写层,使用 Volumes 不会增长容器的体积,而且 Volumes 的内容存储在外部独立于容器的生命周期。若是容器不产生持久化数据,能够考虑使用 tmpfs 内存映射(只保存在容器的内存中)的方式来避免数据存储在其余可能的地方,避免增长容器的体积。
最开始的时候 -v 或者 --volume 选项是给单独容器使用,而 --mount 选项是给集群服务使用。可是从 Docker 17.06 开始,也能够在单独容器上使用 --mount。一般来说 --mount 选项也更加具体和详细。-v 选项将全部选项集中到一个值,而 --mount 选项将可选项分开。若是须要指定 volume driver 选项,那么必须使用 --mount 选项。
# 建立一个数据卷
$ docker volume create my-vol
# 查看全部的数据卷
$ docker volume ls
# 查看指定数据卷的信息
$ docker volume inspect my-vol
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
# 移除指定数据卷的
$ docker volume rm my-vol
# 清除无主的数据卷
$ docker volume prune
复制代码
# 启动一个挂载数据卷的容器
$ docker run -d -P --name web \
-v my-vol:/wepapp \
training/webapp python app.py
$ docker run -d -P --name web \
--mount source=my-vol,target=/webapp \
training/webapp python app.py
# 启动一个挂载数据卷的服务
$ docker service create -d --name devtest-service \
--mount source=myvol2,target=/app \
nginx:latest
复制代码
# 挂载为只读模式
$ docker run -d --name=nginxtest \
-v nginx-vol:/usr/share/nginx/html:ro \
nginx:latest
# type能够分为bind、volume、tmpfs, 默认为volume
# source用于设置数据卷的名称,匿名数据卷能够省略
# target表示须要挂载到容器里面的地方
# readonly表示挂载的内容为只读模式,可选
# volume-opt表示可使用屡次,可选
$ docker run -d --name=nginxtest \
--mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
nginx:latest
复制代码
挂载远程数据卷
# 插件sshfs容许您轻松地在容器中挂载远程文件夹
# 下载该插件
$ docker plugin install --grant-all-permissions vieux/sshfs
# 使用该驱动建立ssh数据卷
$ docker volume create --driver vieux/sshfs \ -o sshcmd=test@node2:/home/test \ -o password=testpassword \ -o port=3336 \ sshvolume
# 启动该驱动程序建立卷建立容器
# 若是两个容器配置了可信关系,就不须要设置volume-opt密码了
$ docker run -d \ --name sshfs-container \ --volume-driver vieux/sshfs \ --mount src=sshvolume,target=/app, \ volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword \ nginx:latest
复制代码
挂载主机目录是将主机中的特定目录直接挂在到容器内部使用
# 使用bind模式启动容器
$ docker run -d -it --name devtest \ -v "$(pwd)"/target:/app \ nginx:latest
$ docker run -d -it --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ nginx:latest
# 看下对应的信息
$ docker inspect devtest
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
# 挂载为只读模式
$ docker run -d -it --name devtest \ -v "$(pwd)"/target:/app:ro \ nginx:latest
$ docker run -d -it --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app,readonly \ nginx:latest
复制代码
$ docker run -d -it --name devtest \ -v "$(pwd)"/target:/app \ -v "$(pwd)"/target:/app2:ro,rslave \ nginx:latest
$ docker run -d -it --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \ nginx:latest
复制代码
内存映射是将内存映射到容器内供容器内部使用
最开始 --tmpfs 是给单独容器使用,而 --mount 选项是给 swarm 集群服务使用的。可是,从 Docker 17.06 开始,也能够在单独容器上使用 --mount 了。一般说来,--mount 更明确,更冗长。最大的区别是 --tmpfs 标志不支持任何可配置选项。其中 --tmpfs 只能在容器中使用,而 swarm 集群则必须使用 --mount 来使用 tmpfs 内存映射。
# 容器上使用
$ docker run -d -it --name tmptest \ --tmpfs /app \ nginx:latest
$ docker run -d -it --name tmptest \ --mount type=tmpfs,destination=/app \ nginx:latest
复制代码
在容器外部查看容器内部的日志输出状况,便于排除和监控问题
能够利用 docker logs 命令,查看 Docker 容器内部应用程序运行时所产生的日志。能够免除首先进入 Docker 容器,再打开应用程序的日志文件的过程。docker logs 会监控容器中操做系统的标准输出设备(STDOUT),一旦 STDOUT 有数据产生,就会将这些数据传输到另外一个设备中,则被称为日志驱动(Logging Driver)。
# 动态查看日志内容
$ docker logs -f netdata
Docker 是怎样作到的呢?咱们使用 docker info 命令,能够看到 Docker 容器的相关信息,其中有一项 Logging Driver 的字段。
# 当前所设置的日志驱动类型
$ docker info | grep 'Logging Driver'
Logging Driver: json-file
复制代码
咱们能够在 docker run 命令中经过 --log-driver 参数来设置具体的 Docker 日志驱动,也能够经过 --log-opt 参数来指定对应日志驱动的相关选项。
docker run -d -p 80:80 --name nginx \
--log-driver json-file \ # 设置日志驱动
--log-opt max-size=10m \ # 表示JSON文件最大为10MB,超过则生成新的文件
--log-opt max-file=3 \ # 表示JSON文件最多保存3个,超过则删除多余文件
nginx
复制代码
# 固然,能够在配置文件中添加,全局生效
$ cat /etc/docker/daemon.json
{
"log-driver": "syslog"
}
# 修改配置以后重启服务
$ sudo systemctl restart docker
复制代码
额外,须要注意的是,默认状况下,Docker 将日志存储到一个日志文件。
# 检查日志文件路径
$ docker inspect --format='{{.LogPath}}' netdata
/var/lib/docker/containers/556553bcb5xxx13cbc588a4-json.log
# 查看实时日志信息
$ tail -f `docker inspect --format='{{.LogPath}}' netdata`
复制代码
上述内容参考: escapelife.github.io/posts/c2e25…
安装完成docker容器服务以后,须要了解如何操做它?在shell命令行下直接输入docker就能够查看帮助信息,以下。
[root@master ~]# docker
Usage: docker COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker")
-D, --debug Enable debug mode
--help Print usage
-H, --host list Daemon socket(s) to connect to (default [])
-l, --log-level string Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
container Manage containers
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
volume Manage volumes
Commands:
attach Attach to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
复制代码
命令不少,重点介绍这20个,请详细阅读下面的文章:
Docker可使用Dockerfile的内容来自动构建镜像。Dockerfile也是一个文件,其中有建立镜像、运行指令等一系列的命令,且每行只支持一个运行命令。
Docker file分为四部分组成:
dockerfile指令忽略大小写,建议大写,#做为注释,每行只支持一条指令,指令能够带多个参数。
dockerfile指令有:
Dockerfile指令一共有如下种:
用来指定基础镜像,而后经过在基础镜像上构建新的镜像,基础镜像通常有远程或本地仓库。而且Dockerfile文件第一行必须的FROM指令,若是一个Dockerfile须要建立多个镜像,可使用多个FROM指令。
#具体使用用法以下:
FROM < image_name > #默认是latest版本
FROM <image:version> #指定版本
复制代码
指定镜像的建立者信息
#具体使用法以下:
MAINTAINER < name >
复制代码
运行全部基础镜像能支持的命令,一样也可使用多条RUN指令,可使用\来换行
#具体使用法以下:
RUN < command >
RUN ["executable", "param1", "param2" ... ] (exec form)
复制代码
用于容器启动时的指定操做,它能够是命令,也能够是脚本,但只执行一次,若是有多少默认只会执行最后一个。
#具体使用法以下:
CMD [“executable” ,”Param1”, “param2”]使用exec执行,推荐
CMD command param1 param2,在/bin/sh上执行
CMD [“Param1”, “param2”] 提供给ENTRYPOINT作默认参数。
复制代码
指定容器的端口映射(容器与物理机),运行容器时加上-p参数指定EXPOSE设置的端口。EXPOSE能够设置多个端口号,相应地运行容器配套屡次使用-p参数。能够经过docker port +容器须要映射的端口号和容器ID来参考宿主机的映射端口。
#具体使用法以下:
EXPOSE <port> [port1 , port2 ............]
复制代码
在镜像中用于设置环境变量的,而后RUN命令可使用此设置的环境变量,在容器启动后也以经过docker inspect查看环境变量,能够经过docker run --env key=value来设置或修改环境变量。
#具体使用法以下:
ENV <key> <value>
ENV JAVA_HOME /usr/local/jdk
复制代码
复制指定的源文件、目录、URL到容器的指定目录中。全部拷贝到container中的文件和文件夹权限为0755,uid和gid为0。
若是源是一个目录,那么会将该目录下的全部文件添加到container中,不包括目录;
若是源文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);
若是源是文件且目标目录中不使用斜杠结束,则会将目标目录视为文件,源的内容会写入目标目录;
若是源是文件且目标目录中使用斜杠结束,则会源文件拷贝到目标目录下。
#具体使用法以下:
ADD <源> <目标>
复制代码
复制本地主机的源(默认为Dockerfile所在的目录)到容器中的目标中,目标路径不存在时会自动建立。
#具体使用法以下:
COPY <源> <目标>
COPY web/index.html /var/web/
复制代码
路径必须是绝对路径,若是不存在,会自动建立对应目录
路径必须是Dockerfile 所在路径的相对路径
若是是一个目录,只会复制目录下的内容,而目录自己则不会被复制
九、ENTRYPOINT
指定容器启动后执行的命令,多行只执行最后一行。而且不可被docker run提供的参数覆盖。
#具体使用法以下:
ENTRYPOINT "command" "param1" "param2"
复制代码
建立一个能够从本地主机或其它容器挂载的挂载点,通常用于存放数据。与docker run -v也能够实现此功能。
#具体使用法以下:
VOLUME [directory_name]
VOLUME /docker_data
复制代码
指定容器运行时使用的用户或UID,后面RUN、CMD、ENTRYPIONT都会使用此用户来运行命令。
#具体使用法以下:
USER [username/uid]
复制代码
指定RUN、CMD、ENTRYPIONT指定的命令的运行目录。可使用多个WORKDIR指令,后续参数若是是相对路径,则会基于以前的命令指定的路径。如:WORKDIR /data WORKDIR work。最终的路径就是/data/work。path路径也能够是环境变量。
#具体使用方法以下:
WORKDIR [path]
复制代码
配置当前所建立的镜像做为其它新建立镜像的基础镜像时,所执行的操做指令。就是,这个镜像建立后,若是其它镜像以这个镜像为基础,会先执行这个镜像的ONBUILD命令。
#具体使用法以下:
ONBUILD [INSTRUCTION]
复制代码
接下来,咱们经过构建一个Tomcat镜像,来演示Dockerfile的使用方法,前提是安装Docker环境,如何安装Docker环境就不在此赘述了。请猛戳下面的文字:
[root@master tomcat]# ll
总用量 190504
-rw-r--r-- 1 root root 9552281 6月 7 15:07 apache-tomcat-8.5.31.tar.gz
-rw-r--r-- 1 root root 32 7月 3 09:41 index.jsp
-rw-r--r-- 1 root root 185515842 9月 20 2017 jdk-8u144-linux-x64.tar.gz
[root@master tomcat]# cat index.jsp
welcome to mingongge's web site
[root@master tomcat]# pwd
/root/docker/tomcat
[root@master tomcat]# vim Dockerfile
#config file start#
FROM centos
MAINTAINER mingongge <微信公众号:民工哥技术之路>
#add jdk and tomcat software
ADD jdk-8u144-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.31.tar.gz /usr/local/
ADD index.jsp /usr/local/apache-tomcat-8.5.31/webapps/ROOT/
#config java and tomcat ENV
ENV JAVA_HOME /usr/local/jdk1.8.0_144
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.31/
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
#config listen port of tomcat
EXPOSE 8080
#config startup command of tomcat
CMD /usr/local/apache-tomcat-8.5.31/bin/catalina.sh run
#end of config-file#
复制代码
构建过程
[root@master tomcat]# docker build -t tomcat-web . #这个.不用注释了吧相信懂的人天然懂的
Sending build context to Docker daemon 195.1 MB
Step 1/11 : FROM centos
---> 49f7960eb7e4
Step 2/11 : MAINTAINER mingongge <微信公众号:民工哥技术之路>
---> Running in afac1e218299
---> a404621fac22
Removing intermediate container afac1e218299
Step 3/11 : ADD jdk-8u144-linux-x64.tar.gz /usr/local/
---> 4e22dafc2f76
Removing intermediate container b1b23c6f202a
Step 4/11 : ADD apache-tomcat-8.5.31.tar.gz /usr/local/
---> 1efe59301d59
Removing intermediate container aa78d5441a0a
Step 5/11 : ADD index.jsp /usr/local/apache-tomcat-8.5.31/webapps/ROOT/
---> f09236522370
Removing intermediate container eb54e6eb963a
Step 6/11 : ENV JAVA_HOME /usr/local/jdk1.8.0_144
---> Running in 3aa91b03d2d1
---> b497c5482fe0
Removing intermediate container 3aa91b03d2d1
Step 7/11 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
---> Running in f2649b5069be
---> 9cedb218a8df
Removing intermediate container f2649b5069be
Step 8/11 : ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.31/
---> Running in 39ef620232d9
---> ccab256164fe
Removing intermediate container 39ef620232d9
Step 9/11 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
---> Running in a58944d03d4a
---> f57de761a759
Removing intermediate container a58944d03d4a
Step 10/11 : EXPOSE 8080
---> Running in 30681437d265
---> b906dcc26584
Removing intermediate container 30681437d265
Step 11/11 : CMD /usr/local/apache-tomcat-8.5.31/bin/catalina.sh run
---> Running in 437790cc642a
---> 95204158ee68
Removing intermediate container 437790cc642a
Successfully built 95204158ee68
复制代码
经过构建的镜像启动容器
[root@master tomcat]# docker run -d -p 8080:8080 tomcat-web
b5b65bee5aedea2f48edb276c543c15c913166bf489088678c5a44fe9769ef45
[root@master tomcat]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b5b65bee5aed tomcat-web "/bin/sh -c '/usr/..." 5 seconds ago Up 4 seconds 0.0.0.0:8080->8080/tcp vigilant_heisenberg
复制代码
浏览器输入http://server-ip:8080, 结果以下:
当咱们执行docker pull xxx的时候,docker默认是从registry.docker.com这个地址上去查找咱们所须要的镜像文件,而后执行下载操做。这类的镜像仓库就是docker默认的公共仓库,全部人均可以直接查看或下载、使用,可是呢,基于网络缘由,下载速度有限制比较慢。所以,咱们在公司内部内网环境中使用dokcer,通常不会将镜像文件上传到公网公共库中。但内部共享使用就是个问题,因此,私有仓库就由此产生了。
私有仓库,就是本地(内网环境)组建的一个与公网公共库功能类似的镜像仓库。组建好以后,咱们就能够将打包好的镜像提交到私有仓库中,这样内网其它用户也可使用这个镜像文件。
本文使用官方提供的registry镜像来组建企业内网的私有镜像仓库
两台安装好docker环境的主机
下载官方registry镜像文件
[root@master ~]# docker pull registry
Using default tag: latest
Trying to pull repository docker.io/library/registry ...
latest: Pulling from docker.io/library/registry
81033e7c1d6a: Pull complete
b235084c2315: Pull complete
c692f3a6894b: Pull complete
ba2177f3a70e: Pull complete
a8d793620947: Pull complete
Digest: sha256:672d519d7fd7bbc7a448d17956ebeefe225d5eb27509d8dc5ce67ecb4a0bce54
Status: Downloaded newer image for docker.io/registry:latest
[root@master ~]# docker images |grep registry
docker.io/registry latest d1fd7d86a825 5 months ago 33.3 MB
复制代码
运行registry容器
[root@master ~]# mkdir /docker/registry -p
[root@master ~]# docker run -itd -v /docker/registry/:/docker/registry -p 5000:5000 --restart=always --name registry registry:latest
26d0b91a267f684f9da68f01d869b31dbc037ee6e7bf255d8fb435a22b857a0e
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
26d0b91a267f registry:latest "/entrypoint.sh /e..." 4 seconds ago Up 3 seconds 0.0.0.0:5000->5000/tcp registry
复制代码
参数说明
1)-itd:在容器中打开一个伪终端进行交互操做,并在后台运行;
2)-v:把宿主机的/docker/registry目录绑定到容器/docker/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
3)-p:映射端口;访问宿主机的5000端口就访问到registry容器的服务了;
4)--restart=always:这是重启的策略,假如这个容器异常退出会自动重启容器;
5)--name registry:建立容器命名为registry,可自定义任何名称;
6)registry:latest:这个是刚才pull下来的镜像;
复制代码
查看远程仓库镜像文件
[root@master ~]# curl http://localhost:5000/v2/_catalog
{"repositories":[]}
复制代码
一样也可使用浏览器访问http://server-ip:5000/v2/_catalog, 结果相同,都是空的没有任何文件。
修改下载的镜像源
[root@slave1 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"]
}
[root@slave1 ~]# systemctl restart docker
复制代码
下载测试镜像
[root@slave1 ~]# docker pull nginx
Using default tag: latest
Trying to pull repository docker.io/library/nginx ...
latest: Pulling from docker.io/library/nginx
683abbb4ea60: Pull complete
6ff57cbc007a: Pull complete
162f7aebbf40: Pull complete
Digest: sha256:636dd2749d9a363e5b57557672a9ebc7c6d041c88d9aef184308d7434296feea
Status: Downloaded newer image for docker.io/nginx:latest
复制代码
给镜像打TAG
[root@slave1 ~]# docker tag nginx:latest 192.168.3.82:5000/nginx:v1
[root@slave1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.3.82:5000/nginx v1 649dcb69b782 8 hours ago 109 MB
docker.io/nginx latest 649dcb69b782 8 hours ago 109 MB
复制代码
上传镜像
[root@slave1 ~]# docker push 192.168.3.82:5000/nginx:v1
The push refers to a repository [192.168.3.82:5000/nginx]
Get https://192.168.3.82:5000/v1/_ping: http: server gave HTTP response to HTTPS client
#注意这里出现报错提示,从提示信息能够看出须要使用https的方式才能上传,解决方案以下:
[root@slave1 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"],
"insecure-registries":["192.168.3.82:5000"]
}
#添加私有镜像服务器的地址,注意书写格式为json,有严格的书写要求,须要重启docker服务生效配置
[root@slave1 ~]# systemctl restart docker
[root@slave1 ~]# docker push 192.168.3.82:5000/nginx:v1
The push refers to a repository [192.168.3.82:5000/nginx]
6ee5b085558c: Pushed
78f25536dafc: Pushed
9c46f426bcb7: Pushed
v1: digest: sha256:edad5e71815c79108ddbd1d42123ee13ba2d8050ad27cfa72c531986d03ee4e7 size: 948
复制代码
从新查看镜像仓库
[root@master ~]# curl http://localhost:5000/v2/_catalog
{"repositories":["nginx"]}
[root@master ~]# curl http://localhost:5000/v2/nginx/tags/list
{"name":"nginx","tags":["v1"]}
#查看有哪些版本
复制代码
测试下载
#首先删除客户端主机以前从公共库下载下来的镜像文件
[root@slave1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.3.82:5000/nginx v1 649dcb69b782 10 hours ago 109 MB
docker.io/nginx latest 649dcb69b782 10 hours ago 109 MB
[root@slave1 ~]# docker image rmi -f 649dcb69b782
Untagged: 192.168.3.82:5000/nginx:v1
Untagged: 192.168.3.82:5000/nginx@sha256:edad5e71815c79108ddbd1d42123ee13ba2d8050ad27cfa72c531986d03ee4e7
Untagged: docker.io/nginx:latest
Untagged: docker.io/nginx@sha256:636dd2749d9a363e5b57557672a9ebc7c6d041c88d9aef184308d7434296feea
Deleted: sha256:649dcb69b782d4e281c92ed2918a21fa63322a6605017e295ea75907c84f4d1e
Deleted: sha256:bf7cb208a5a1da265666ad5ab3cf10f0bec1f4bcb0ba8d957e2e485e3ac2b463
Deleted: sha256:55d02c20aa07136ab07ab47f4b20b97be7a0f34e01a88b3e046a728863b5621c
Deleted: sha256:9c46f426bcb704beffafc951290ee7fe05efddbc7406500e7d0a3785538b8735
[root@slave1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
#此时客户端全部的镜像文件所有删除
[root@slave1 ~]# docker pull 192.168.3.82:5000/nginx:v1
Trying to pull repository 192.168.3.82:5000/nginx ...
v1: Pulling from 192.168.3.82:5000/nginx
683abbb4ea60: Pull complete
6ff57cbc007a: Pull complete
162f7aebbf40: Pull complete
Digest: sha256:edad5e71815c79108ddbd1d42123ee13ba2d8050ad27cfa72c531986d03ee4e7
Status: Downloaded newer image for 192.168.3.82:5000/nginx:v1
[root@slave1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.3.82:5000/nginx v1 649dcb69b782 11 hours ago 109 MB
#能够看出,客户端已正常从远端服务器拉取到所须要的镜像文件,其它内网服务器也能够正常共享这台镜像服
复制代码
以上步骤就是经过使用docker Registry快速搭建私有镜像仓库的过程与测试。我也其实也能够经过:利用 Harbor 搭建企业级私有镜像仓库。
Docker是一项很是流行的容器技术,如今在各行各业有着普遍的使用。不过如何管理Docker容器是一个问题,因此我今天向你们介绍两款Docker可视化工具,但愿对你们有所帮助。
Portainer是一款Docker可视化管理工具,容许咱们在网页中方便的查看和管理Docker容器。
要使用Portainer很简单,运行下面两条命令便可。这些命令会建立一个Portainer专用的卷,而后在8000和9000端口建立容器并运行。
$ docker volume create portainer_data$ docker run --name portainer -d -p 8000:8000 -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
复制代码
而后在浏览器打开对应地址,就会发现成功运行了。第一次运行的时候须要设置帐号,而后选择要管理的Docker主机。 设置帐号
选择要管理的主机
以后就能够看到本机上运行的Docker容器了,点击它们还能够进行容器的管理。左边的条目能够管理卷、建立容器、查看主机信息等等。基本上该有的功能都有了,这也是我推荐的一个工具。
LazyDocker是基于终端的一个可视化查询工具,支持键盘操做和鼠标点击。相比Portainer来讲可能不那么专业,不过对于开发者来讲可能反而更加好用了。由于通常开发者都是使用命令行来运行Docker,偶尔须要图形化查看的时候,就可使用LazyDocker这个工具。
官网演示图
安装LazyDocker也很是简单,运行下面的命令便可。
docker run --rm -it -v \/var/run/docker.sock:/var/run/docker.sock \-v ~/.config/lazydocker:/.config/jesseduffield/lazydocker \lazyteam/lazydocker
复制代码
固然若是发现LazyDocker挺好用,准备常用的话,还能够把它作成缩写添加到shell配置文件中,这样就能够将它变成一个简单的命令。例如我用的是zsh,就将下面这样添加到.zshrc文件中。之后就能够直接用lzd来调用LazyDocker了。
alias lzd='docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v ~/.config/lazydocker:/.config/jesseduffield/lazydocker lazyteam/lazydocker'
复制代码
而后就能够在终端中查看Docker容器、镜像和卷的信息了。LazyDocker支持键盘操做和鼠标点击,直接用鼠标点击就能够查看对应信息了。
须要注意若是你的终端LazyDocker的图形显示的是乱的,不用担忧,只不过是显示字体的问题。从新设置一下终端字体就能够解决了。
以上内容来自:www.toutiao.com/i6780014313…
Docker 社区已经建立了许多开源工具,它们能帮咱们处理各类用例。做者在本文中推荐了 5 款认为最有用的 Docker 工具,分别是 Watchtower(自动更新 Docker 容器)、docker-gc(容器和镜像的垃圾回收)、docker-slim(容器瘦身)、 rocker:突破 Dockerfile 的限制,以及 ctop(容器的类顶层接口)。 Docker 社区已经建立了许多开源工具,它们所能帮你处理的用例甚至会超出你的想象。 你能够在网上找到不少酷炫的 Docker 工具,其中大部分是开源的,均可以在 Github 上找到。在过去的两年里,我很是热衷于 Docker,在大多数开发项目中都使用了它。当你开始使用 Docker 后,你会发现它适用的场景比你最初预想的还更多。你会但愿 Docker 尽量为你多作一点事,而它不会让你失望的! Docker 社区很是活跃,天天都会出现许多有用的工具,时时关注社区中发生的全部创新是很困难的。为了帮助你,我收集了一些我在平常工做中使用的又有趣又实用的 Docker 工具,这些工具提高了个人工做效率,减小了本来须要手工完成的工做。
向你们推荐一些实用工具:你应该知道的5个开源Docker工具...,Docker 服务终端 UI 管理工具,你们最终根据本身的使用习惯与实际生产需求来选择合适本身的工具来管理Docker容器。
随着线上服务的全面docker化,对docker容器的监控就很重要了。SA的监控系统是物理机的监控,在一个物理机跑多个容器的状况下,咱们是无法从一个监控图表里面区分各个容器的资源占用状况的。
推荐你们看看这篇:打造高逼格、可视化的Docker容器监控系统平台
在平时的工做中,docker 接触得不少,除了常用的 docker run ,docker stop 等命令,docker 还有不少十分有用可是却不常用的命令,下面就来总结一下:
这个命令是用来查看一个容器里面的进程信息的,好比你想查看一个 nginx 容器里面有几个 nginx 进程的时候,就能够这么作:
docker top 3b307a09d20d
UID PID PPID C STIME TTY TIME CMD
root 805 787 0 Jul13 ? 00:00:00 nginx: master process nginx -g daemon off;
systemd+ 941 805 0 Jul13 ? 00:03:18 nginx: worker process
复制代码
我通常使用这两个命令去下载打包 Kubernetes 的镜像,由于你知道的国内的网速并不像国外那么快。
docker save 能够把一个镜像保存到 tar 文件中,你能够这么作:
~ docker save registry:2.7.1 >registry-2.7.1.tar
#同时 docker load 能够把镜像从 tar 文件导入到 docker 中
~ docker load < registry-2.7.1.tar
复制代码
这个命令能够帮助你在命令行中方便的搜索 DockerHub 中的镜像,好比:
~ docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 13519 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1846 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 780 [OK]
linuxserver/nginx An Nginx container, brought to you by LinuxS… 123
bitnami/nginx Bitnami nginx Docker Image 87 [OK]
tiangolo/nginx-rtmp Docker image with Nginx using the nginx-rtmp… 85 [OK]
jc21/nginx-proxy-manager Docker container for managing Nginx proxy ho… 73
alfg/nginx-rtmp NGINX, nginx-rtmp-module and FFmpeg from sou… 71 [OK]
nginxdemos/hello NGINX webserver that serves a simple page co… 57 [OK]
jlesage/nginx-proxy-manager Docker container for Nginx Proxy Manager 53 [OK]
nginx/nginx-ingress NGINX Ingress Controller for Kubernetes 37
......
复制代码
固然这个功能在国内可能不会特别好用,由于......
这个命令能够帮助你实时获取 docker 的各类事件信息,好比建立了一个容器什么的。
~ docker events
2020-07-28T21:28:46.000403018+08:00 image load sha256:432bf69f0427b52cad10897342eaf23521b7d973566354118e9a59c4d31b5fae (name=sha256:432bf69f0427b52cad10897342eaf23521b7d973566354118e9a59c4d31b5fae)
复制代码
当你 docker run 了以后却发现里面有一些参数并非你想要的状态好比你设置的 nginx 容器 cpu 或者内存过小,这个时候你就可使用 docker update 去修改这些参数。
~ docker update nginx --cpus 2
复制代码
当你修改了一个镜像,可是忘记了每一层的修改命令,或者你想查看一个镜像是怎么构建的时候就可使用这个命令,好比:
~ docker history traefik:v2.1.6
IMAGE CREATED CREATED BY SIZE COMMENT
5212a87ddaba 5 months ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 5 months ago /bin/sh -c #(nop) CMD ["traefik"] 0B
<missing> 5 months ago /bin/sh -c #(nop) ENTRYPOINT ["/entrypoint.… 0B
<missing> 5 months ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 5 months ago /bin/sh -c #(nop) COPY file:59a219a1fb7a9dc8… 419B
<missing> 5 months ago /bin/sh -c set -ex; apkArch="$(apk --print-… 52.9MB
<missing> 5 months ago /bin/sh -c apk --no-cache add ca-certificate… 1.85MB
<missing> 6 months ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 6 months ago /bin/sh -c #(nop) ADD file:a1906f14a4e217a49… 4.81MB
复制代码
这个命令能够查看容器的退出状态,好比:
~ docker wait 7f7f0522a7d0
0
复制代码
这样你就能够知道这个容器是正常退出的仍是异常退出的了。
当你运行了一个容器可是想要暂停它运行的时候,你就可使用这个命令。
~ docker pause 7f7f0522a7d0
复制代码
当你运行了一个容器,可是你不知道容器里修改了哪一些文件的时候可使用这个命令,好比:
~ docker diff 38c59255bf6e
C /etc
A /etc/localtime
C /var
C /var/lib
A /var/lib/registry
复制代码
这个是 docker 内置的监控命令,当你想要查看当前主机下全部容器占用内存和 cpu 的状况的时候就可使用这个命令。
~ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
1c5ade04e7f9 redis 0.08% 17.53MiB / 47.01GiB 0.04% 10.9GB / 37GB 0B / 0B 4
afe6d4ebe409 kafka-exporter 0.09% 16.91MiB / 47.01GiB 0.04% 1.97GB / 1.53GB 752MB / 0B 23
f0c7c01a9c34 kafka-docker_zookeeper 0.01% 308.8MiB / 47.01GiB 0.64% 20.2MB / 12.2MB 971MB / 3.29MB 28
da8c5008955f kafka-docker_kafka-manager 0.08% 393.2MiB / 47.01GiB 0.82% 1.56MB / 2.61MB 1.14GB / 0B 60
c8d51c583c49 kafka-docker_kafka 1.63% 1.256GiB / 47.01GiB 2.67% 30.4GB / 48.9GB 22.3GB / 5.77GB 85
......
复制代码
不少人最终仍是决定使用 Docker 解决问题。 Docker 的优势不少,好比:
尽管如此,众多用户仍然只是把容器当作常见的虚拟机,而忘记了容器的一个重要特性: 正由于这一特色,一些用户须要改变他们对容器的观念,为了更好的使用与发挥 Docker 容器的价值,有一些事情是绝对不该该作的:
容器可能会被中断、被替换或遭到破坏。在容器中运行的 1.0 版应用程序很容易就会被 1.1 版取代,而不会对数据形成影响或致使数据丢失。所以,若是须要存储数据,请存储在卷 (volume) 中。在这一状况下,还应注意两个容器是否会在同一个卷上写入数据,这将致使损坏。请确保应用程序适用于写入共享的数据存储。
因此他们大多会认为,应该将应用程序部署到现有正在运行的容器中。在须要不断部署和调试的开发阶段,可能确实如此;但对于 QA 和生产的持续交付 (CD) 渠道,应用程序应当是镜像的一部分。切记:容器转瞬即逝。
大尺寸的镜像难以分配。请确保仅使用必需文件和库来运行应用程序。不要安装没必要要的数据包,也不要运行“更新”(yum update),这些操做会把大量文件下载到新的镜像层。
为了有效利用多层文件系统,请始终为操做系统建立属于本身的基本镜像层,而后为用户名定义建立一个层,为运行时安装建立一个层,为配置建立一个层,最后再为应用程序建立一个层。这样,从新建立、管理和分配镜像就会容易些。
换句话说,不要使用"docker commit"命令来建立镜像。这一镜像建立方法不可复制,所以应彻底避免使用。请始终使用 Dockerfile 或其余任何可彻底复制的 S21(从源代码到镜像)方法,如此一来,若是存储在源代码控制存储库 (GIT) 中,就能够跟踪 Dockerfile 的变动状况。
最新版标签就像 Maven 用户的“快照”(SNAPSHOT) 同样。容器具备多层文件系统这一基本特征,因此咱们鼓励使用标签。相信谁也不肯意在构建了几个月的镜像后,忽然发现应用程序由于父层(即 Dockerfile 中的 FROM)被新版本取代而没法运行(新版本没法向后兼容或从构建缓存中检索的“最新“版有误)这样的意外吧?在生产过程当中部署容器时也应避免使用”最新版“标签,这是由于没法跟踪当前运行的镜像版本。
容器只运行一个进程(HTTP 守护进程、应用程序服务器、数据库)时效果最佳,但若是运行一个以上进程,在管理和检索日志以及单独更新进程时就会遇到不少麻烦。
不要在镜像中对任何用户名/密码进行硬编码操做。请使用环境变量从容器外部检索信息。Postgres 镜像就是这一原理的极佳诠释。
“默认状况下,Docker 容器以 root 用户权限运行。随着 Docker 技术日趋成熟,可以使用的安全默认选项愈来愈多。目前,要求 root 对其余用户来讲较为危险,另外,不是全部环境都可以使用 root。镜像应使用 USER 指令来为容器的运行指定非 root 用户。”(摘自《Docker 镜像做者指南》(Guidance for Docker Image Authors))
每一个容器都有本身的内部 IP 地址,若是启动而后中止容器,内部 IP 地址可能会发生变化。若是你的应用程序或微服务须要和另外一个容器进行通讯,请使用环境变量在容器之间传递相应的主机名和端口。
监控已经愈来愈受到开发者们的重视,实时监控 Docker 的方法,这里推荐 Cloudinsight。 不一样于一些须要自写脚本的监控手段,Cloudinsight 做为一家免费的 SaaS 服务,可以一键监控 Docker,且拥有很棒的可视化界面。除此以外,Cloudinsight 还支持多种操做系统、数据库等的监控,可以一体化展现全部被监控的系统基础组件的性能数据。
原文:my.oschina.net/cllgeek/blo…
工做流程:
1,部署git
若是公司内部有直接克隆就能够
git clone git@192.168.0.31:/home/git/solo.git
复制代码
2,部署Jenkins环境
部署传送门:Jenkins+Maven+Svn实现代码自动打包与发布
3,部署私有镜像仓库
注意:docker 仓库 因为https 认证,全部须要pull的客户端,须要修改配置文件
[root@linux-node1 ~]# vim /etc/sysconfig/docker
# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled --insecure-registry 192.168.56.11:5000'
复制代码
4,全部主机安装docker
1)安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2`
2)添加Docker软件包源:
yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo
3)安装Docker CE
yum install docker-ce -y`
4)配置加速器
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://bc437cce.m.daocloud.io`
#由于默认源会去国外获取数据,因此会慢能够超时,这是咱们就须要配置加速器指向国内源https://www.daocloud.io/
5)启动并开机启动
# systemctl start docker
# systemctl enable docker
复制代码
【Apache、Nginx、Tomcat、LNMP、LAMP、LNTP】
JAVA程序必须有JDK环境才能够运行,为了减小镜像大小及提升性能,这里直接把JDK放到宿主机上,容器以挂载形式使用。
1,安装jdk
#rz 把tar包上传,解压后放到指定目录
rz.......
tar -zxvf jdk-8u60-linux-x64.tar.gz
mv jdk1.8.0_60 /usr/local/jdk1.8
复制代码
2,拟写Dockerfile
# cat Dockerfile
FROM centos:7
#他的妈妈是谁
MAINTAINER www.aliangedu.com
#他的爸爸是谁
ENV VERSION=8.5.33
#tomcat版本
ENV JAVA_HOME /usr/local/jdk
#jdk 绝对路径
RUN yum install wget -y
#运行的命令
RUN wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz &&
tar zxf apache-tomcat-${VERSION}.tar.gz &&
mv apache-tomcat-${VERSION} /usr/local/tomcat &&
rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* &&
mkdir /usr/local/tomcat/webapps/ROOT
EXPOSE 8080
#程序使用的端口
CMD /usr/local/tomcat/bin/catalina.sh run
#执行tomcat目录下的启动脚本,这里面遇到坑,就是-v 将宿主机jdk目录挂在到容器/usr/local/jdk 时候,由于镜像按照dockerfile去打,那么在执行命令的时候就会找不到路径,因此我临时删除了,EXPOSE与CMD 2行,而后从新打包,使用 -p 指定端口,而后进入容器,手工启动tomcat的方式,进行
复制代码
3,构建镜像
docker build -t 192.168.56.11:5000/tomcat-85:latest -f dockerfile .
#最后这个点。表明当前路径,在制做镜像时,会记录上下文内容
复制代码
4,上传到docker 镜像仓库
root@node02 scripts]# docker push 192.168.56.11:5000/tomcat-85:latest
复制代码
5,启动镜像 测试
[root@node02 scripts]# docker run -it -d -p 8080:8080 -v /usr/local/jdk1.8:/usr/local/jdk 192.168.56.11:5000/tomcat-8:latest
[root@3addff07c464 ROOT]# echo "123" >index.jsp
复制代码
1.主页面 -> 系统管理 -> 全局工具配置
指定JDK、Maven路径,Git保持默认:
2.jenkins安装必要插件
主页面 -> 系统管理 ->管理插件:
安装SSH与Git Parameter插件。
插件说明:
3,配置SSH插件
第一步:先建立一个用于链接Docker主机的凭证 (有权限的用户)
主页面 -> 凭据 -> 系统 -> 右击全局凭据 -> 添加凭据:
输入链接Docker主机的用户名和密码:
第二步:添加SSH远程主机
主页面 -> 系统管理 -> 系统设置 -> SSH remote hosts:
问题:当以普通用户身份去使用docker images时,出现如下错误:
# git clone https://github.com/b3log/solo
# cd solo
移除旧的推送地址,添加新的:
# git remote remove origin
# git remote add origin git@gitlab.example.com:qqq/solo.git
提交代码到Git仓库并建立tag:
# touch src/main/webapp/a.html
# git add .
# git commit -m “a”
建立标签:
# git tag 1.0.0
推送到Git服务器:
# git push origin 1.0.0
复制代码
登录gitlab查看solo项目:
1.主页面 -> 新建任务 -> 输入任务名称,构建一个Maven项目:
注意:若是没有显示“构建一个Maven项目”选项,须要在管理插件里安装“Maven Integration plugin”插件。
配置Git参数化构建:
2.动态获取Git仓库tag,与用户交互选择Tag发布:【也能够设置分支】
3.指定项目Git仓库地址:
修改*/master为$Tag,Tag是上面动态获取的变量名,表示根据用户选择打代码版本。
4.设置maven构建命令选项:
clean package -Dmaven.test.skip=ture
利用pom.xml文件构建项目。
在Jenkins本机镜像构建与推送到镜像仓库,并SSH远程链接到Docker主机使用推送的镜像建立容器:
上图中 命令内容以下:
REPOSITORY=192.168.56.11:5000/solo:${Tag}
# 构建镜像
cat > Dockerfile << EOF
FROM 192.168.56.11:5000/tomcat-8:latest
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY target/*.war /usr/local/tomcat/webapps/ROOT.war
CMD ["/usr/local/tomcat/bin/catalina.sh", "run"]
EOF
docker build -t $REPOSITORY .
# 上传镜像
docker push $REPOSITORY
复制代码
上图中Command 内容以下:
REPOSITORY=192.168.56.11:5000/solo:${Tag}
# 部署
sudo docker rm -f blog-solo |true
sudo docker image rm $REPOSITORY |true
sudo docker container run -d --name blog-solo -v /usr/local/jdk1.8:/usr/local/jdk -p 8080:8080 $REPOSITORY
# -d 后台运行 ,-v 挂在目录,-p 映射端口,后面是镜像
复制代码
注:容器名称blog-solo,暴露宿主机端口8080,即便用宿主机IP 192.168.56.12:8080 访问blog-solo项目。
blog-solo项目已配置完成,开始构建:
选择tag,开始构建:
点击左下角构建历史里,右击第一个查看控制台输出:
构建详细内容
构建成功
访问:192.168.56.12:8080 查看部署结果
调整项目访问地址
进入容器,切换到项目目录
vi WEB-INF/classes/latke.properties
#### Server ####
# Browser visit protocol
serverScheme=http
# Browser visit domain name
serverHost=192.168.56.12
# Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=8080
复制代码
调整后,重启tomcat,再次验证,OK,结果以下:
至此,自动化CI环境搭建完成,你能够模拟提交代码并打tag测试自动化发布流程。
查看docker.sock权限
[root@node03 ~]# ll /var/run/docker.sock
srw-rw---- 1 root docker 0 9月 4 21:55 /var/run/docker.sock
复制代码
解决方法:【免sudo 使用docker images 】
[root@node03 ~]# sudo groupadd docker
##groupadd:“docker”组已存在
[root@node03 ~]# sudo gpasswd -a jenkins docker
##正在将用户“jenkins”加入到“docker”组中
[root@node03 ~]# sudo service docker restart
##重启服务
[root@node03 ~]# newgrp - docker
##从新加载group 组信息,必定要输入这条命令,不然没法加载最新组内容,由于有缓存
复制代码
原文:www.toutiao.com/a6602838654…
这里主要是为了记录在使用 Docker 的时候遇到的问题及其处理解决方法。
默认状况系统会将 Docker 容器存放在/var/lib/docker 目录下
问题原由:今天经过监控系统,发现公司其中一台服务器的磁盘快慢,随即上去看了下,发现 /var/lib/docker 这个目录特别大。由上述缘由,咱们都知道,在 /var/lib/docker 中存储的都是相关于容器的存储,因此也不能随便的将其删除掉。
那就准备迁移 docker 的存储目录吧,或者对 /var 设备进行扩容来达到相同的目的。更多关于 dockerd 的详细参数,请点击查看 官方文档 地址。
可是须要注意的一点就是,尽可能不要用软链, 由于一些 docker 容器编排系统不支持这样作,好比咱们所熟知的 k8s 就在内。
# 发现容器启动不了了
ERROR:cannot create temporary directory!
# 查看系统存储状况
$ du -h --max-depth=1
复制代码
解决方法1:添加软连接
# 1.中止docker服务
$ sudo systemctl stop docker
# 2.开始迁移目录
$ sudo mv /var/lib/docker /data/
# 3.添加软连接
# sudo ln -s /data/docker /var/lib/docker
# 4.启动docker服务
$ sudo systemctl start docker
复制代码
解决方法2:改动 docker 配置文件
# 3.改动docker启动配置文件
$ sudo vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --graph=/data/docker/
# 4.改动docker启动配置文件
$ sudo vim /etc/docker/daemon.json
{
"live-restore": true,
"graph": [ "/data/docker/" ]
}
复制代码
操做注意事项:在迁移 docker 目录的时候注意使用的命令,要么使用 mv 命令直接移动,要么使用 cp 命令复制文件,可是须要注意同时复制文件权限和对应属性,否则在使用的时候可能会存在权限问题。若是容器中,也是使用 root 用户,则不会存在该问题,可是也是须要按照正确的操做来迁移目录。
# 使用mv命令
$ sudo mv /var/lib/docker /data/docker
# 使用cp命令
$ sudo cp -arv /data/docker /data2/docker
复制代码
下图中,就是由于启动的容器使用的是普通用户运行进程的,且在运行当中须要使用 /tmp 目录,结果提示没有权限。在咱们导入容器镜像的时候,实际上是会将容器启动时须要的各个目录的权限和属性都赋予了。若是咱们直接是 cp 命令单纯复制文件内容的话,就会出现属性不一致的状况,同时还会有必定的安全问题。
写着写着,字数超出限制了,OMG,更多疑难解答请查阅:彻夜怒肝!Docker 常见疑难杂症解决方案已撸完,快要裂开了。。。
史上最全、最详细的Docker学习资料 推荐给你看一看。
推荐给你们:推荐 11 个极易上手的 Docker 实践项目