Docker初步

烈酒焚心 提交于 2020-03-09 19:40:27

一、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
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 版本

镜像加速

官方仓库:https://hub.docker.com

鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决,我使用的是阿里云的镜像。

登录阿里云并进入容器镜像服务页面,就会显示为你独立分配的加速地址和操作步骤:

阿里云仓库:https://dev.aliyun.com/search.html

三、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守护进程 的概念:

Docker服务端 提供了一系列 REST API(Docker Remote API),当我们执行 Docker 命令时实际上是通过 API 和 Docker服务端进行交互。

参考文档:https://docs.docker.com/develop/sdk/

官方提供的连接方式有:

  • 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/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!