Docker 是一个开源的应用容器引擎,而一个容器其实是一个虚拟化的独立的环境,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker 的局限性之一,它只能用在 64 位的操作系统上。
Docker 从1.13 版本之后采用时间线的方式作为版本号,分为社区版CE 和企业版EE,社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施、容器、插件等。
社区版按照stable 和edge 两种方式发布,每个季度更新stable 版本,如17.06,17.09;每个月份更新edge 版本,如17.09,17.10。
下面教程运行在Centos 中
Docker 官方的安装教程,在这里。
安装一些必要的系统工具
sudo yuminstall-y yum-utils device-mapper-persistent-data lvm2添加软件源信息
# docker 官方源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可选:启用edge 和test 存储库。 这些存储库包含在上面的docker.repo 文件中,但默认情况下处于禁用状态。您可以将它们与稳定存储库一起启用。
$ sudo yum-config-manager --enable docker-ce-edge$ sudo yum-config-manager --enable docker-ce-test您可以通过使用--disable 标志运行yum-config-manager 命令来禁用边缘或测试存储库。 要重新启用它,请使用--enable 标志。 以下命令禁用edge 存储库:
$sudo yum-config-manager--disable docker-ce-edge$sudo yum-config-manager--disable docker-ce-test安装 Docker-ce
# 安装前可以先更新 yum 缓存:sudo yum makecache fast# 安装 Docker-cesudo yuminstall docker-ce如果你想安装特定docker-ce 版本,先列出 repo 中可用版本,然后选择安装
$ yum list docker-ce--showduplicates|sort-r# docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable# docker-ce.x86_64 18.06.1.ce-3.el7 @docker-ce-stable# docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable# docker-ce.x86_64 18.03.1.ce-1.el7.centos docker-ce-stable# docker-ce.x86_64 18.03.0.ce-1.el7.centos docker-ce-stable# docker-ce.x86_64 17.12.1.ce-1.el7.centos docker-ce-stable# 选择版本安装$sudo yuminstall docker-ce-<VERSION STRING># 选择安装 docker-ce-18.06.1.ce$sudo yuminstall docker-ce-18.06.1.ce启动 Docker 后台服务
$sudo systemctl startdocker通过运行hello-world 镜像,验证是否正确安装了docker。
$docker run hello-worldyuminstalldocker# CentOS 中安装apt-getinstall docker-ce# Ubuntu 中安装pacman-Sdocker# Arch 中安装emerge--askdocker# Gentoo 中安装#=====================docker version# 通过查看版本,检查安装是否成功# Client:# Version: 1.12.6# API version: 1.24# Package version: docker-1.12.6-55.gitc4618fb.el7.centos.x86_64# Go version: go1.8.3# Git commit: c4618fb/1.12.6# Built: Thu Sep 21 22:33:52 2017# OS/Arch: linux/amd64## Server:# Version: 1.12.6# API version: 1.24# Package version: docker-1.12.6-55.gitc4618fb.el7.centos.x86_64# Go version: go1.8.3# Git commit: c4618fb/1.12.6# Built: Thu Sep 21 22:33:52 2017# OS/Arch: linux/amd64$docker--help管理命令: container 管理容器 image 管理镜像 network 管理网络命令: attach 介入到一个正在运行的容器 build 根据 Dockerfile 构建一个镜像 commit 根据容器的更改创建一个新的镜像cp 在本地文件系统与容器中复制 文件/文件夹 create 创建一个新容器exec 在容器中执行一条命令 images 列出镜像kill 杀死一个或多个正在运行的容器 logs 取得容器的日志 pause 暂停一个或多个容器的所有进程ps 列出所有容器 pull 拉取一个镜像或仓库到 registry push 推送一个镜像或仓库到 registryrename 重命名一个容器 restart 重新启动一个或多个容器rm 删除一个或多个容器 rmi 删除一个或多个镜像 run 在一个新的容器中执行一条命令 search 在 Docker Hub 中搜索镜像 start 启动一个或多个已经停止运行的容器 stats 显示一个容器的实时资源占用 stop 停止一个或多个正在运行的容器 tag 为镜像创建一个新的标签top 显示一个容器内的所有进程 unpause 恢复一个或多个容器内所有被暂停的进程servicedocker start# 启动 docker 服务,守护进程servicedocker stop# 停止 docker 服务servicedocker status# 查看 docker 服务状态chkconfigdocker on# 设置为开机启动镜像可以看做我们平时装系统的镜像,里面就是一个运行环境。
docker pull centos:latest# 从docker.io中下载centos镜像到本地docker images# 查看已下载的镜像docker rmi[image_id]# 删除镜像,指定镜像id# 删除所有镜像# none 默认为 docker.iodocker rmi$(docker images|grep none|awk'{print $3}'|sort-r)# 连接进行进入命令行模式,exit命令退出。docker run-t-i nginx:latest /bin/bash由于国区已经无法访问,可以将镜像打包,直接安装镜像压缩文件
$docker pull gitlab/gitlab-ce:17.2.0-ce.0# 下载镜像$docker pull--platform linux/amd64 gitlab/gitlab-ce:17.2.0-ce.0$docker pull--platform linux/amd64 portainer/portainer-ce:2.20.3-alpine$docker pull--platform linux/amd64 portainer/agent:2.20.3-alpine# 保存 Docker 镜像到本地文件$docker save-o[output-file.tar][image-name]$docker save-o gitlab-ce.0-17.2.0.tar gitlab/gitlab-ce:17.2.0-ce.0$docker save-o portainer-agent-2.20.3-alpine.tar portainer/agent:2.20.3-alpine$docker save-o portainer-ce-2.20.3-alpine.tar portainer/portainer-ce:2.20.3-alpine将镜像文件发送到服务器
$scp[output-file.tar][user]@[server-ip]:[path]$scp gitlab-ce-17.0.1.tar root@110.55.8.163:/home/docker-images服务器上加载 Docker 镜像
$docker load-i /home/docker-images/gitlab-ce-17.0.1.tar# 加载 Docker 镜像$docker images# 验证镜像是否加载成功我们可以通过以下两种方式对镜像进行更改。
下面通过已存在的容器创建一个新的镜像。
docker commit-m="First Docker"-a="wcjiang" a6b0a6cfdacf wcjiang/nginx:v1.2.1上面命令参数说明:
-m 提交的描述信息-a 指定镜像作者a6b0a6cfdacf 记住这个是容器id,不是镜像idwcjiang/nginx:v1.2.1 创建的目标镜像名假设创建一个 node.js 镜像,首先在 node.js 项目根目录创建文件。
touch Dockerfile .dockerignore.dockerignore 文件内容,下面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。
.gitnode_modulesnpm-debug.logDockerfile 文件内容
FROM node:8.4COPY . /appWORKDIR /appRUN npm install --registry=https://registry.npm.taobao.orgEXPOSE 3000FROM node:8.4:该image 文件继承官方的node image,冒号表示标签,这里标签是8.4,即8.4版本的node。COPY . /app:将当前目录下的所有文件(除了.dockerignore 排除的路径),都拷贝进入image 文件的/app 目录。WORKDIR /app:指定接下来的工作路径为/app。RUN npm install:在/app目录下,运行npm install 命令安装依赖。注意,安装后所有的依赖,都将打包进入image 文件。EXPOSE 3000:将容器3000 端口暴露出来, 允许外部连接这个端口。有了Dockerfile 文件以后,就可以使用docker image build 命令创建image 文件了。
$docker image build-t koa-demo.# 或者$docker image build-t koa-demo:0.0.1.上面命令,-t 参数用来指定image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。注意后面有个.,表示 Dockerfile 文件所在的路径为当前路径
docker run--name koa-demo-name--rm-d-p9066:3000 koa-demo:latest# 或者docker run--name koa-demo-name--rm-d-p9066:3000 koa-demo:0.0.1上面命令,将刚创建的koa-demo 景象跑起来,命令的--rm 参数,在容器终止运行后自动删除容器文件。
docker tag wcjiang/nginx:v1.2.1 wcjiang/nginx-test:lastestdocker loginnginx-test镜像docker push wcjiang/nginx-test:lastest# The push refers to a repository [docker.io/wcjiang/nginx-test]# 2f5c6a3c22e3: Mounted from wcjiang/nginx# cf516324493c: Mounted from wcjiang/nginx# lastest: digest: sha256:73ae804b2c60327d1269aa387cf782f664bc91da3180d10dbd49027d7adaa789 size: 736通常情况下,使用docker官方镜像,如 mysql镜像,默认情况下镜像中啥软件也没有,通过下面命令安装你所需要的软件:
# 第一次需要运行这个命令,确保源的索引是最新的# 同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引apt-get update# 做过上面更新同步之后,可以运行下面的命令了apt-getinstallvim如果你安装了CentOS或者Ubuntu系统可以进入系统安装相关软件
# 进入到centos7镜像系统docker run-i-t centos:7 /bin/bashyum updateyuminstallvim容器就像一个类的实例
# 列出本机正在运行的容器docker containerls# 列出本机所有容器,包括终止运行的容器docker containerls--alldocker start[containerID/Names]# 启动容器docker stop[containerID/Names]# 停止容器dockerrm[containerID/Names]# 删除容器docker logs[containerID/Names]# 查看日志dockerexec-it[containerID/Names] /bin/bash# 进入容器# 从正在运行的 Docker 容器里面,将文件拷贝到本机,注意后面有个【点】拷贝到当前目录docker containercp[containID]:[/path/to/file].docker run centosecho"hello world"# 在docker容器中运行hello world!docker run centos yuminstall-ywget# 在docker容器中,安装wget软件dockerps# 列出包括未运行的容器dockerps-a# 查看所有容器(包括正在运行和已停止的)docker logs my-nginx# 查看 my-nginx 容器日志docker run-i-t centos /bin/bash# 启动一个容器docker inspect centos# 检查运行中的镜像docker commit 8bd centos# 保存对容器的修改docker commit-m"n changed" my-nginx my-nginx-image# 使用已经存在的容器创建一个镜像docker inspect-f{{.State.Pid}} 44fc0f0582d9# 获取id为 44fc0f0582d9 的PID进程编号# 下载指定版本容器镜像docker pull gitlab/gitlab-ce:11.2.3-ce.0docker run-itd--name my-nginx2 nginx# 通过nginx镜像,【创建】容器名为 my-nginx2 的容器docker start my-nginx--restart=always# 【启动策略】一个已经存在的容器启动添加策略# no - 容器不重启# on-failure - 容器推出状态非0时重启# always - 始终重启docker start my-nginx# 【启动】一个已经存在的容器docker restart my-nginx# 【重启】容器docker stop my-nginx# 【停止运行】一个容器dockerkill my-nginx# 【杀死】一个运行中的容器dockerrename my-nginx new-nginx# 【重命名】容器dockerrm new-nginx# 【删除】容器docker run-itd my-nginx /bin/bashdocker ps查看到该容器信息dockerps# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES# 6bd0496da64f nginx "/bin/bash" 20 seconds ago Up 18 seconds 80/tcp high_shirleydocker exec命令进入一个已经在运行的容器dockerexec-it 6bd0496da64f /bin/bash通常有下面几种方式进入Docker的容器,推荐使用exec,使用attach 一直进入失败。
docker attachSSH为什么不需要在 Docker 容器中运行 sshdnsenter进入Docker容器,nsenter官方仓库docker exec,在1.3.*之后提供了一个新的命令exec用于进入容器从主机复制到容器sudo docker cp host_path containerID:container_path
从容器复制到主机sudo docker cp containerID:container_path host_path
通过官方提供的私有仓库镜像registry来搭建私有仓库。通过humpback 快速搭建轻量级的Docker容器云管理平台。关于仓库配置说明请参见configuration.md
⚠️ 注意:也可以通过部署管理工具
Harbor来部署registry
registrydocker pull registry:2.6.2创建容器并运行,创建成功之后,可访问http://192.168.99.100:7000/v2/,来检查仓库是否正常运行,当返回{} 时,表示部署成功。
docker run-d\-p5000:5000\--restart=always\--name registry\ registry:2# 自定义存储位置docker run-d\-p5000:5000\--restart=always\--name registry\-v$HOME/_docker/registry:/var/lib/registry\ registry:2docker run-d-p5000:5000--restart=always--name registry\-v`pwd`/config.yml:/etc/docker/registry/config.yml\ registry:2推送镜像到私有仓库
# 从官方仓库拉取一个镜像docker pull nginx:1.13# 为镜像 `nginx:1.13` 创建一个新标签 `192.168.31.69:7000/test-nginx:1.13`docker tag nginx:latest192.168.31.69:5000/test-nginx:1.13# 推送到私有仓库中docker push192.168.31.69:5000/test-nginx:1.13# The push refers to a repository [192.168.99.100:7000/test-nginx]# Get https://192.168.99.100:7000/v1/_ping: http: server gave HTTP response to HTTPS client在推送到的时候报错误,默认是使用https 提交,这个搭建的默认使用的是http,解决方法两个:
https 映射我们使用第二种方法,加入到不安全的仓库列表中,修改docker配置文件vi /etc/docker/daemon.json 添加insecure-registries 配置信息,如果daemon.json 文件不存在可以创建,关键配置项,将仓库将入到不安全的仓库列表中。
{"insecure-registries":["192.168.31.69:5000"]}如果是 macOS 可以通过 docker 客户端,
Preferences=>Advanced=>添加配置=>Apply & Restart,重启docker就可以了。
重启服务service docker restart,默认情况下 push 是会报如下错误的:
docker push192.168.99.100:7000/test-nginx:1.13# The push refers to a repository [192.168.99.100:7000/test-nginx]# a1a53f8d99b5: Retrying in 1 second# ...# received unexpected HTTP status: 500 Internal Server Error上面错误是SELinux 强制访问控制安全系统,阻止导致的错误,通过下面方法禁用 SELinux 之后就可以 push 了。
setenforce0getenforce# Permissive# 停止本地 registrydocker container stop registry# 要删除容器,请使用 docker container rmdocker container stop registry&&docker containerrm-v registry# 自定义存储位置HarborDocker 不仅可以通过本地命令行docker 命令进行调用,还可以通过开启远程控制API,使用HTTP 调用接口来进行访问,远程控制Docker Daemon 来做很多操作。Docker 的远程API 服务默认监听的是 TCP2375 端口,为了保证安全,Docker 安装后默认不会启用远程API 服务,因为这个服务默认不做权限认证。
CentOS 的开启方法比较简单,先修改配置:
vim /usr/lib/systemd/system/docker.service# 修改 `ExecStart` 配置项,默认如下:ExecStart=/usr/bin/dockerd-H fd://--containerd=/run/containerd/containerd.sock# 增加一个 `-H tcp://0.0.0.0:2375` 选项ExecStart=/usr/bin/dockerd-H fd://-H tcp://0.0.0.0:2375--containerd=/run/containerd/containerd.sock如果是内网生产环境,也可以将0.0.0.0 改为内网 IP。同样的,2375 端口也可以修改。但是这样可能还有一个问题,无法在命令行使用docker 命令了,还需要添加sock 选项:-H unix:///var/run/docker.sock,最后为:
ExecStart=/usr/bin/dockerd-H fd://-H unix:///var/run/docker.sock-H tcp://10.105.3.115:2375--containerd=/run/containerd/containerd.sock修改完配置之后需要重启 Docker 服务:
systemctl daemon-reloadsystemctl restartdockersudoservicedocker restart重启完成后,可以使用 netstat 查看端口是否监听来确认是否成功:
[root@VM-3-115-centos ~]# netstat -nutlp | grep 2375tcp0010.105.3.115:23750.0.0.0:* LISTEN32316/dockerd在 Mac 下无法直接修改配置文件来开启远程 API 服务,后来在docker/for-mac 的issue 中得到了解决方案。
可以运行一个bobrik/socat 容器,将unix socket 上的 Docker API 转发到 MacOS 上指定的端口中:
docker run-d-v /var/run/docker.sock:/var/run/docker.sock-p127.0.0.1:2375:2375 bobrik/socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock启用成功后,可以进行一些测试,例如直接使用浏览器访问 info 和 version 等页面获取信息。
http://127.0.0.1:2375/infohttp://127.0.0.1:2375/version下面可测试 docker 是否启动了
curl-s --unix-socket /var/run/docker.sock http://dummy/containers/json## 或者使用下面命令docker info⚠文件挂载注意:docker 禁止用主机上不存在的文件挂载到 container 中已经存在的文件
-d,--detach=false# 指定容器运行于前台还是后台,默认为false-i,--interactive=false# 打开STDIN,用于控制台交互-t,--tty=false# 分配tty设备,该可以支持终端登录,默认为false-u,--user=""# 指定容器的用户-a,--attach=[]# 登录容器(必须是以docker run -d启动的容器)-w,--workdir=""# 指定容器的工作目录-c, --cpu-shares=0# 设置容器CPU权重,在CPU共享场景使用-e,--env=[]# 指定环境变量,容器中可以使用该环境变量-m,--memory=""# 指定容器的内存上限-P, --publish-all=false# 指定容器暴露的端口-p,--publish=[]# 指定容器暴露的端口-h,--hostname=""# 指定容器的主机名-v,--volume=[]# 给容器挂载存储卷,挂载到容器的某个目录--volumes-from=[]# 给容器挂载其他容器上的卷,挂载到容器的某个目录--cap-add=[]# 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities--cap-drop=[]# 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities--cidfile=""# 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法--cpuset=""# 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU--device=[]# 添加主机设备给容器,相当于设备直通--dns=[]# 指定容器的dns服务器--dns-search=[]# 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件--entrypoint=""# 覆盖image的入口点--env-file=[]# 指定环境变量文件,文件格式为每行一个环境变量--expose=[]# 指定容器暴露的端口,即修改镜像的暴露端口--link=[]# 指定容器间的关联,使用其他容器的IP、env等信息--lxc-conf=[]# 指定容器的配置文件,只有在指定--exec-driver=lxc时使用--name=""# 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字--net="bridge"# 容器网络设置:# bridge 使用docker daemon指定的网桥# host //容器使用主机的网络# container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源# none 容器使用自己的网络(类似--net=bridge),但是不进行配置--privileged=false# 指定容器是否为特权容器,特权容器拥有所有的capabilities--restart="no"# 指定容器停止后的重启策略:# no:容器退出时不重启# on-failure:容器故障退出(返回值非零)时重启# always:容器退出时总是重启--rm=false# 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)--sig-proxy=true# 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理NginxMySQLPostgreSQLRedisElasticsearchGitlabRocket.ChatRancherPortainerSourcegraphMattermostSeaweedFSNPSPenpotNavidromeJenkinsHumpback首先创建放持久化数据文件夹,mkdir -p /opt/app/humpback-web,里面存放持久化数据文件,会存储站点管理和分组信息,启动后请妥善保存。
# 创建放持久化数据文件夹mkdir-p /opt/app/humpback-web# 下载humpback-web镜像到本地docker pull humpbacks/humpback-web:1.0.0# 启动 humpback-web 容器,将容器命名为 humpback-webdocker run-d--net=host--restart=always\-eHUMPBACK_LISTEN_PORT=7001\-v /opt/app/humpback-web/dbFiles:/humpback-web/dbFiles\--name humpback-web\ humpbacks/humpback-web:1.0.0访问站点,打开浏览器输入:http://192.168.99.100:7001 ,默认账户:admin 密码:123456
Seafiledocker run-d--name seafile\-eSEAFILE_SERVER_HOSTNAME=seafile.example.com\-v /opt/seafile-data:/shared\-p80:80\ seafileltd/seafile:latestdocker run-d--name seafile\-eSEAFILE_SERVER_HOSTNAME=pan.example.com\-eSEAFILE_ADMIN_EMAIL=wcj@example.com\-eSEAFILE_ADMIN_PASSWORD=wcj@example.com\-v$HOME/_docker/seafile-data:/shared\-p80:80\ seafileltd/seafile:latest移除旧的版本
$sudo yum removedocker\ docker-client\ docker-client-latest\ docker-common\ docker-latest\ docker-latest-logrotate\ docker-logrotate\ docker-selinux\ docker-engine-selinux\ docker-engineCreate more free space in thin pool or use dm.min_free_space option to change behavior
特别慎用,东西都没有了,注意备份哦。https://github.com/moby/moby/issues/3182#issuecomment-256532928
镜像拉不下来
修改 Dockerdaemon.json 配置 macOS:/etc/docker/daemon.json,Linux:~/.docker/daemon.json
{"registry-mirrors":["https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com","https://mirror.baidubce.com","https://registry.docker-cn.com"],"insecure-registries":["192.168.188.111:2021"]}As always, thanks to our amazing contributors!
Made withaction-contributors.
Licensed under the MIT License.