Docker虚拟化管理:30分钟教你学会用Docker

优惠码优惠 2020-05-02

docker mysql 配置 tomcat 镜像 容器 ADD cmd

Docker虚拟化管理:30分钟教你学会用Docker

关于Docker的官方介绍网上太多了我就不贴了,就实际体验来说Docker可以极大的简化环境搭建及服务部署的操作流程,大大降低部署的时间成本,解放你的双手。

本文不会深入讲解Docker底层架构及运行原理,也不会有一堆架构图贴在这里。该篇旨在让你以最快的速度学会使用Docker,关于Docker的架构及其底层的一些知识,你可以在学会Docker的基本使用之后再去了解。开门见山讲架构聊底层有点容易让人犯迷糊,但在使用Docker之前你至少应该了解他的三大核心组件:仓库、镜像和容器,以及他们之前的关系。本文将通过一个MySQL示例带你了解并使用Docker,待你对Docker有一个基本了解后你再回头去看他的体系架构会容易理解。

三大核心组件
仓库:仓库是集中存储镜像的地方,我们本地安装Docker之后,需要从仓库中拉取镜像。可以类比于Maven,有公有仓库和私有仓库之分。

镜像:是一个Linux的文件系统,它里面存放着可以再Linux内核中运行的程序及其数据。

容器:是镜像创建的运行实例,可以把它理解为一个精简版的Linux系统,里面运行着镜像里的程序。

为了更好的让你理解这三者的关系,我打一个不恰当但很形象的比方,镜像就相当于你weixin.exe文件,容器相当于你安装好的微信程序,微信程序(容器)需要你的weixin.exe文件(镜像)来安装(创建),那么仓库就相当于应用商店了,你可以从商店下载你要的.exe文件(镜像)。

微信程序安装完成后你可以选择运行或者关闭,Docker容器一样可以运行和停止,微信程序你可以从系统卸载,Docker容器你同样可以选择删除。

但有一点不同的地方是,weixin.exe文件安装完成你就可以删除了,它和你的微信程序并没有关系,删掉安装文件不影响你微信程序的运行。但是镜像不同,如果有容器正在使用这个镜像,那么这个镜像是不能删除的(删除时会报Error不让你删)。

首发地址:https://www.guitu18.com/post/2020/01/20/66.html

安装Docker
CentOS安装Docker要求:

必须是64位操作系统
内核版本在3.8以上
你可以通过uname -r查看你的系统内核:

[root@localhost ~]# uname -r
3.10.0-1062.18.1.el7.x86_64
[root@localhost ~]#
yum方式安装:

yum install docker -y
安装完成你可以通过docker version查看你的docker版本信息:

[root@localhost ~]# docker version
Client:
Version: 1.13.1
API version: 1.26
Package version: docker-1.13.1-109.gitcccb291.el7.centos.x86_64
Go version: go1.10.3
Git commit: cccb291/1.13.1
Built: Tue Mar 3 17:21:24 2020
OS/Arch: linux/amd64

Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Package version: docker-1.13.1-109.gitcccb291.el7.centos.x86_64
Go version: go1.10.3
Git commit: cccb291/1.13.1
Built: Tue Mar 3 17:21:24 2020
OS/Arch: linux/amd64
Experimental: false
[root@localhost ~]#
看到如上的信息说明你的Docker安装成功,你可以用 docker info 命令查看更详细的信息。

配置镜像加速
为了更愉快的使用Docker你可能还需要配置镜像加速,可以类比于Maven的私服,使用国内的镜像仓库能让你更快的拉取镜像。

执行vim /etc/docker/daemon.json,修改为如下配置:

{

"registry-mirrors":[
    "https://reg-mirror.qiniu.com/",
    "https://hub-mirror.c.163.com/"
]

}
重新加载配置及重启Docker服务:

systemctl daemon-reload
systemctl restart docker
执行docker info你可以看到镜像仓库配置已经生效了。

拉取镜像
Docker安装和配置都搞定了,现在你要从仓库下载镜像了,这里以 MySQL 5.7 为例:

5.7为版本号,你也可以安装其他版本

docker pull mysql:5.7

拉取成功后通过docker images命令查看本地镜像:

[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/mysql 5.7 f965319e89de 3 hours ago 448 MB
[root@localhost ~]#
创建容器
有了镜像,你需要用它创建一个容器才能运行,创建并运行MySQL容器:

docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
命令参数说明(后面会有更加详细的说明):
-d:后台运行
-p:端口映射,前面的为宿主机端口,后面的为容器端口,这里我将宿主机的3306端口指向了容器的3306端口
--name:为启动的容器命名
-e:指定容器内的环境变量,这里指配置MySQL的Root用户密码为:123456

执行成功后会返回容器ID,查看已创建的容器:docker ps -a

[root@localhost ~]# docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
8e1cd060075db23c61cb31cecb3a3321df92cf56ea7086476cc21e8709382d19
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8e1cd060075d mysql:5.7 "docker-entrypoint..." 3 seconds ago Up 1 second 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
[root@localhost ~]#
可以看到刚才创建的MySQL容器已经在运行了,现在你可以通过${IP}:3306连接MySQL数据库了(记得放行端口或者关闭防火墙)。

挂载目录
通过上面的步骤,你已经通过Docker运行起你的第一个容器MySQL了,而且你也能通过宿主机的端口连接到容器中的MySQL。但这样做还不是很安全,关于这个我们要先简单了解一下容器和宿主机之间的关系。

容器内和宿主机的文件系统是独立的(虽然整个容器也是以文件的形式存放在宿主机的某个目录上的),包括他们之间的网络,也是独立的。刚才运行的MySQL容器有一个 -p 3306:3306 的参数,这个参数就是映射宿主机和容器之间的端口的,你也可以配置成比如 -p 1234:3306 ,这样你通过访问宿主机的1234端口就能访问到容器的3306端口。

那么再回到文件系统,容器本身也是一个精简版的Linux系统,只不过他运行在宿主机上依赖于宿主机的硬件。容器内部也是有着一套独立的文件系统的,且随着容器的删除,所有存在于容器内的所有文件都将被清除。刚才我们创建的那个MySQL容器,只要我们删除容器,数据库里的所有数据都将清除,这显然不是我们想看到的。

Docker的run命令提供了一个-v的参数,允许我们容器内部目录挂载为宿主机的本地目录,这样容器内的程序在操作这个目录时,其实操作的是宿主机的目录。那么我们可以把程序运行的关键数据挂载到宿主机上的目录,比如MySQL的数据库文件,程序运行的日志文件等等。这样一来当我们在删除容器时,因为这些目录是存在于宿主机的,所以不会随着容器一起删除,从而实现了容器数据的持久化。

还是以刚才的MySQL容器为例,我们先删掉刚才的容器:

mysql为容器名称,也可以是容器ID,通过 docker ps -a 查看容器信息

docker stop mysql
docker rm mysql
接着用下面的命令创建并运行MySQL容器,增加了一个 -v 参数:

在宿主机创建挂载目录

mkdir -p /usr/local/mysql/conf
mkdir -p /usr/local/mysql/logs
mkdir -p /usr/local/mysql/data

创建并运行容器

docker run -p 3306:3306 --name mysql \
-v /usr/local/mysql/conf:/etc/mysql \
-v /usr/local/mysql/logs:/var/log/mysql \
-v /usr/local/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7
-v /usr/local/mysql/data:/var/lib/mysql

表示将宿主机的 /usr/local/mysql/data 目录挂载到容器内的 /var/lib/mysql 目录,那么容器内的MySQL程序操作的数据实际上是写入了宿主机的 /usr/local/mysql/data 目录了,其他两项同理。

这里挂载的三个目录分别为数据库运行的配置、日志和数据,也是MySQL程序最重要的数据,即便这个容器删除了,只要这些数据还在,我们就能通过重新创建容器恢复全部数据。

而且这样挂载以后,我们无需进入容器,直接在宿主机操作这几个目录里的文件就能同步体现到容器内部,比如修改一些配置,导出数据之类的,不用进入容器直接在宿主机操作即可。

用以上命令运行容器之后,在你的宿主机的/usr/local/mysql/data 目录就能看到MySQL运行生成的数据库文件了:

Docker的数据卷挂载(我习惯称之为挂载目录)功能非常重要,我们运行的任何程序都有需要持久化的数据,如果这些数据直接放在容器内部是非常不安全的。而且挂载目录还可以实现直接在宿主机操作容器内的数据,也能做到容器间的数据共享,用Docker一定要养成挂载重要数据到宿主机的习惯。

错误排查
上面这个命令是直接后台运行容器的,如果需要调试可以把 -d 参数修改为 -it 参数以在前台运行,在某些情况下你很可能会遇到类似于下面这些错误(可以通过前台运行查看到):

chown: changing ownership of '/var/lib/mysql/': Permission denied

或者

mysqld: Can't create/write to file '/var/lib/mysql/is_writable' (Errcode: 13 - Permission denied)
如果出现上述问题,那么你需要关闭SELINUX,方法如下:

临时关闭:setenforce 0
永久关闭:vim /etc/selinux/config,修改 SELINUX 的值为 disabled 然后重启机器即可,看图:

再次运行容器就能看到成功提示了。

常用命令
通过上面的示例基本已经知道了Docker是怎样工作的,下面是一些基本命令,包括最常用的目录挂载功能等命令说明:

docker version|info

显示Docker信息,常用于查看Docker版本或检测Docker是否正确安装。

docker images

列出机器上的镜像(images)及信息:REPOSITORY、TAG、IMAGE ID、CREATED、SIZE。

IMAGE ID列其实是缩写,要显示完整则带上--no-trunc选项。

-a 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层)

-no-trunc 显示完整的镜像信息

-q 静默模式,只显示镜像ID

docker search tomcat

在docker index中搜索image,搜索的范围是官方镜像和所有个人公共镜像。NAME列的 / 后面是仓库的名字。

docker pull tomcat

从docker registry server 中下拉image或repository。

语法:docker pull [OPTIONS] NAME[:TAG|@DIGEST]

-a 拉取所有 tagged 镜像

--disable-content-trust 忽略镜像的校验,默认开启

上面的命令没有指定参数,在docker v1.2版本及以前,会下载官方镜像的tomcat仓库里的所有镜像

而从v.13开始只会下载tag为latest的镜像,也可以明确指定具体的镜像

如:docker pull tomcat:8,后面的8为tomcat版本tag。

docker run -d --name tomcat -p 8081:8080 tomcat:8

启动容器,语法为:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

-d 后台运行容器,并返回容器ID,不使用-d我们会看到tomcat启动日志,此时Ctrl+C容器会停止运行。

-e 指定容器内的环境变量

-name 指定容器的名称,如果不指定docker会帮我们取一个名字。

-p 端口映射,宿主机端口:容器端口,上面我们就将宿主机的8081映射到容器的8080端口

此时我们访问宿主机的ip:8081就能访问容器内的tomcat了。

-i 以交互模式运行容器,通常与 -t 同时使用。

-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用

-v 目录挂载,本地目录:容器目录

docker ps

查看容器的信息,默认显示当前正在运行中的容器

-a 查看所有容器

-l 显示最新启动的一个容器(包括已停止的)

docker start|stop|restart CONTAINER_ID

启动/停止/重启容器,需要用到容器ID,可以使用docker ps -a 查看所有容器的ID。

docker attach CONTAINER_ID|NAME

进入容器,后面跟容器ID或者NANE,可以使用docker ps -a 查看所有容器的ID。

可以认为这是一个过时的命令,更多的docker用户会考虑使用docker exec来实现相同的功能

但是出于docker官方并没有删除这个命令,我们还是有必要学习一下的。

进入容器后输入exit命令可以退出,同时容器停止运行,如若想退出但不停止容器,可以用快捷键Ctrl+P+Q退出。

docker exec -i -t CONTAINER_ID|NAME /bin/bash

进入容器,推荐使用这种方式。

语法:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

-i 以交互模式运行容器,通常与 -t 同时使用。

-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用

示例:docker exec -it mycentos /bin/sh /root/start.sh

上面这条命令表示在容器 mycentos 中以交互模式执行容器内 /root/start.sh 脚本

docker rm CONTAINER_ID|NAME

删除一个或多少容器,如:docker rm $(docker ps -a -q),为删除所有停止的容器

-l 移除容器间的网络连接,而非容器本身

-v 删除与容器关联的卷

-f 通过SIGKILL信号强制删除一个运行中的容器

docker rmi CONTAINER_ID|NAME

删除本地一个或多少镜像

-f 强制删除;

--no-prune 不移除该镜像的过程镜像,默认移除;

docker build

使用 Dockerfile 创建镜像,语法:docker build [OPTIONS] PATH | URL | -

-f 指定要使用的Dockerfile路径

-t,--tag 指定镜像的名字及标签:name:tag或者name,可以在一次构建中为一个镜像设置多个标签

Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

初学者一开始可不必关注Dockerfile,待你熟悉Docker的整个体系结构及其运行方式后,再回头看这个就会一目了然了。

FROM

指定基础镜像,必须为第一个命令

FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>

示例

FROM docker.io/centos:latest

MAINTAINER

维护者信息

MAINTAINER <name>

示例

MAINTAINER guitu "xianjian-mail@qq.com"

RUN

用于在镜像容器中执行命令,其有以下两种命令执行方式

shell执行

RUN <command>

exec执行

RUN ["executable", "param1", "param2"]

示例

RUN apk update
RUN ["executable", "param1", "param2"]
RUN ["/etc/execfile", "arg1", "arg1"]

RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。

如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

ADD

将当前目录下的文件复制到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
# 第二中形式用于支持包含空格的路径

示例

ADD hom* /mydir/          # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/

可以是Dockerfile所在目录的一个相对路径,也可以是一个URL,还可以是一个tar文件(会自动解压为目录)

如果文件或目录不与Dockerfile在同一目录会提示 no such file or directory

COPY

功能类似ADD,但是是不会自动解压文件,也不能访问网络资源

CMD

构建容器后调用,也就是在容器启动时才进行调用。

CMD ["executable","param1","param2"](执行可执行文件,优先)
CMD ["param1","param2"](设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)

示例

CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]

CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

ENTRYPOINT

配置容器,使其可执行化。配合CMD可省去"application",只使用参数。

ENTRYPOINT ["executable", "param1", "param2"](可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)

示例

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。

Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。

LABEL

用于为镜像添加元数据

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例

LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"

使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。

推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。

ENV

设置环境变量

ENV <key> <value>  
# <key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
ENV <key>=<value> ...  
# 可以设置多个变量,每个变量为一个"<key>=<value>"的键值对
# 如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行

示例

ENV JAVA_HOME /docker/jdk

VOLUME

用于指定持久化目录

VOLUME ["/path/to/dir"]

示例

VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

# 卷可以容器间共享和重用
# 容器并不一定要和其它容器共享卷
# 修改卷后会立即生效
# 对卷的修改不会对镜像产生影响
# 卷会一直存在,直到没有任何容器在使用它

WORKDIR

工作目录,类似于cd命令

WORKDIR /path/to/workdir

示例

WORKDIR /a  (这时工作目录为/a)
WORKDIR b  (这时工作目录为/a/b)
WORKDIR c  (这时工作目录为/a/b/c)

通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。

在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

USER

指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。

使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

  USER user
  USER user:group
  USER uid
  USER uid:gid
  USER user:gid
  USER uid:group

示例

  USER www

使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。

镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

ARG

用于指定传递给构建运行时的变量

ARG <name>=[<default value>]

示例

ARG site
ARG build_user=www

ONBUILD

用于设置镜像触发器

  ONBUILD [INSTRUCTION]

示例

  ONBUILD ADD . /app/src
  ONBUILD RUN /usr/local/bin/python-build --dir /app/src

当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发

构建镜像
了解了上面的命令之后,我们可以尝试着创建我的第一个自制镜像了,以下是我的Dockerfile示例:

使用的基础镜像

FROM docker.io/centos:latest

作者信息

MAINTAINER guitu "xianjian-mail@qq.com"

安装SVN

RUN yum install -y subversion

添加JAVA环境,下方的文件请换成你Dockerfile目录下的文件,压缩包在构建镜像时会自动解压

ADD jdk-8u231-linux-x64.tar.gz /docker/
ADD apache-tomcat-8.0.53.tar.gz /docker/

添加环境变量

ENV JAVA_HOME /docker/jdk1.8.0_231
ENV TOMCAT_HOME /docker/apache-tomcat-8.0.53
ENV PATH $PATH:$JAVA_HOME/bin:$TOMCAT_HOME/bin

指定工作目录

WORKDIR /docker/apache-tomcat-8.0.53

暴露8080端口

EXPOSE 8080

启动时运行tomcat

CMD ["bin/startup.sh && tail -f logs/catalina.out"]
通过Dockerfile创建镜像:

docker build -t mytomcat8:v0.1 .
通过Dockerfile文件构建镜像完成。

原文地址https://www.cnblogs.com/guitu18/p/12815168.html

登录 后评论
下一篇
云栖号资讯小编
11804人浏览
2020-07-13
相关推荐
iOS开发体验优化方案
58人浏览
2020-08-07 16:54:20
数据科学家Docker入门指南
2262人浏览
2018-09-09 12:20:38
30 分钟快速入门 Docker 教程
2675人浏览
2019-04-10 01:02:01
使用docker搭建渗透测试环境
5883人浏览
2017-06-13 09:51:00
如何在 CentOS 7 上安装 Docker
1318人浏览
2017-05-02 11:18:00
0
0
0
531