Docker初步
一、Docker 简介
Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现:
二、Docker 安装部署
下载说明:https://docs.docker.com/install/linux/docker-ce/centos/
Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务,个人开发者一般用不到。
检查 Linux 内核版本
Docker 要求 Linux 系统的内核版本高于 3.10,通过 uname -r 命令查看你当前的内核版本:
依赖安装
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-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Docker 安装
sudo yum install docker-ce -y
Docker 启动
systemctl start docker
systemctl enable docker
加入 Docker 用户组
Docker 安装时默认创建了 docker 用户组,将普通用户加入 docker 用户组就可以不使用 sudo 来操作 docker:
sudo usermod -aG docker 用户名
改变当前用户的有效群组:
newgrp - docker
查看 Docker 版本
镜像加速
鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决,我使用的是阿里云的镜像。
登录阿里云并进入容器镜像服务页面,就会显示为你独立分配的加速地址和操作步骤:
阿里云仓库:https://dev.aliyun.com/search.html
速度太慢可以使用这个下载安装:http://get.daocloud.io/#install-compose
三、Docker 容器基本操作
相关命令:
docker create 容器名或者容器ID # 创建容器 docker start [-ai] 容器名 # 启动容器 docker run 容器名或者容器ID # 运行容器,相当于docker create + docker start docker ps [-a] # 查看正在运行的/所有容器 docker attach 容器名或者容器ID # 进入容器的命令行 docker exec 容器名 COMMAND # 在运行的容器中执行命令 docker stop 容器名 # 停止容器 docker rm 容器名 # 删除容器 docker top 容器名 # 查看WEB应用程序容器的进程 docker inspect 容器名 # 查看Docker的底层信息
Docker 命令请参考文档:https://docs.docker.com/engine/reference/commandline/docker
3.1 images 文件
Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。
# 列出本机的所有 image 文件 $ docker image ls # 删除 image 文件 $ docker image rm [imageName]
image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。
3.2 获取镜像
通过 docker pull 命令可以从远程仓库下载需要的镜像到本地,如从阿里云仓库查找 CentOS 官方镜像:
复制镜像地址后,粘贴并执行:
3.3 从镜像中创建容器并运行
docker run 会先把镜像放入容器(只在第一次运行),就是 docker create 和 docker start 两个命令的组合,支持参数也是一致的:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
选项:
- -a stdin:指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项
- -d:后台运行容器,并返回容器ID
- -i:以交互模式运行容器,通常与 -t 同时使用
- -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=[]:开放一个端口或一组端口
- --publish 或 -p:将容器的端口发布到主机
映射端口运行
docker run -d -p 8080:80 名称或ID
-p 表示把容器的80端口映射到宿主机的8080端口
运行交互式容器
docker run -i -t --name myos1 centos
此时我们已进入一个 centos 镜像的容器,可以通过运行 exit 命令或者使用 ctrl+d 退出,当然也会同时停止该容器的运行。
可以通过 docker start 再次启动容器:
docker start 容器ID
执行 docker exec 容器名 COMMAND 命令可以在运行的容器中执行命令:
所以,当 docker exec 命令执行 /bin/bash 时就相当于进入了容器的终端。并且相比于 docker attach 命令,该命令当 exit 退出该容器时并不会同时停止该容器的运行(需要加入 -i 和 -t 参数):
1
可以看到, exit 退出 myos1 容器后,该容器依然在运行状态。
3.4 使用 Dockerfile 构建镜像
Docker 可以通过 Dockerfile 的内容来自动构建镜像。Dockerfile 是一个包含创建镜像所有命令的文本文件,通过 docker build 命令可以根据 Dockerfile 的内容构建镜像。
Dockerfile 官方文档:https://docs.docker.com/engine/reference/builder/
接下来在之前纯净版 Centos7 镜像的基础上安装一个 Apache,构建一个新的镜像。创建文件 Dockerfile :
FROM centos:latest RUN yum install httpd -y RUN systemctl enable httpd.service EXPOSE 80
然后通过 docker build 命令读取 Dockerfile 文件创建镜像,也可以使用 -f 参数指定 Dockerfile 文件:
docker build -t centos:httpd .
我在第一次执行 docker build 时报如下错误:
原因是 docker 容器内没有网络。我的解决方法:
1)编辑 /etc/sysctl.conf(Linux 内核参数配置文件),加入一行内容:
net.ipv4.ip_forward=1
2)保存退出后执行:
systemctl restart network
3)最后重启 docker 服务:
systemctl restart docker
执行 docker images 可以看到出现了一个新镜像叫做 centos,只不过标签变成了 httpd:
镜像创建成功后,启动该容器:
docker run --privileged -d -p 8080:80 --name myhttpd centos:httpd /usr/sbin/init
以上命令在容器启动时,执行 /usr/sbin/init 。 --privileged 参数表示:给容器加特权,否则交互式方式进入容器无法操作一些譬如修改内核、修改系统参数、甚至启动服务等。
容器和主机间的数据共享
通过 docker run 的 -v 参数可以在容器中设置一个挂载点:
docker run --privileged -d -p 8080:80 --name myhttpd -v /home/txl/www:/var/www/html centos:myhttpd /usr/sbin/init
上面的命令将主机上的 /home/txl/www 目录中被映射到容器中的 /var/www/html 下,这时我们容器中操作该目录或在主机中操作,两者均是实时同步。
3.5 Docker 管理工具—portainer 的简单使用
Portainer 是 Docker 的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm 集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
Github 地址:https://github.com/portainer/portainer
官网:https://portainer.readthedocs.io/en/latest/deployment.html
准备工作:配置 Docker 远程连接
Docker客户端 和 Docker守护进程 的概念:
官方提供的连接方式有:
- unix:///var/run/docker/sock(默认连接方式)
- tcp://host:port
- fd://socketfd
可以通过 ps -ef | grep docker 查看
参考文档:https://docs.docker.com/engine/reference/commandline/dockerd/#examples
配置远程连接实例:
1)编辑 /usr/lib/systemd/system/docker.service 文件
2)将原本 ExecStart=/usr/bin/dockerd 该行内容注释
3)新增 ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
然后保存并重启 Docker:
systemctl daemon-reload
systemctl restart docker
最后再次查看:
Docker 此时已经成功开放 TCP 连接的 2375 端口。
继续安装 portainer:
1)拉取镜像:
docker pull portainer/portainer
2)运行容器:
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer:/data --name myportainer portainer/portainer
3)访问服务器 9000 端口,设置管理员账号以及Docker 服务器的远程连接地址(如之前设置的:x.x.x.x:2375):
参考
《Docker —— 从入门到实践》:https://yeasy.gitbooks.io/docker_practice/content/