Docker简单上手01

    科技2024-10-12  27

    前言

    之前也有听说过docker但是因为没有具体的业务接触所以并没有具体的去了解过,最近手头的工作也暂时没有那么急所以趁着时间来看下。

    准备

    系统:CentOS 7.6 64位

    查看Linux核心版本,3.10版本及以上才可以安装docker

    uname -r

    更新yum包

    yum update

    查看docker是否曾经安装过

    whereis docker // 如果安装过,则删除之前的版本 yum remove docker docker-common docker-selinux docker-engine

    安装需要的软件包

    yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的

    yum install -y yum-utils device-mapper-persistent-data lvm2

    设置yum源

    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

    安装

    默认安装最新版本

    yum install docker-ce

    安装某特定版本需增加版本号(如18.06.3.ce-3.el7)

    yum install docker-ce-18.06.3.ce

    配置用户

    将 docker 的权限移交给非 root 用户,这样使用 docker 就不需要每次都 sudo 了:

    sudo usermod -aG docker $USER

    启动

    systemctl start docker

    注销用户或者重启之后就会生效。然后通过 systemd 服务配置 Docker 开机启动:

    systemctl enable docker

    验证安装是否成功

    docker version

    如果存在Client和Server则成功

    下载并安装 docker-compose

    curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

    配置并测试docker-compose

    chmod +x /usr/local/bin/docker-compose docker-compose version

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3FrxuNg-1602064860477)(https://tothers.top1buyer.com/WeChatf12c620346c9dac34e1fb7e84c0bb781.png)]

    配置镜像仓库

    默认的镜像仓库 Docker Hub 在国外,国内拉取速度比较感人。建议参考这篇文章配置镜像加速

    到这里前期的准备和环境安装工作就完成了,下面就开始上手实践吧!

    上手实验

    实例一:Hello World!

    按照惯例,我们运行胰腺癌来自Docker的Hello World:

    docker run hello-world

    这个过程中Docker做了以下事情:

    检查本地是否有指定的 hello-world:latest 镜像(latest 是镜像标签,后面会细讲),如果没有,执行第 2 步,否则直接执行第 3 步。本地没有指定镜像(Unable to find xxx locally),从 Docker Hub 下载到本地。根据本地的 hello-world:latest 镜像创建一个新的容器并运行其中的程序。运行完毕后,容器退出,控制权返回给用户。

    实例二:运行一个Nginx服务器

    运行以下命令:

    docker run -p 8080:80 nginx

    运行之后,你会发现一直卡住,也没有任何输出,但放心你的电脑并没有死机。让我们打开浏览器访问localhost:8080(如果像我一样用的服务器可以打开服务器域名:8080来查看)

    打开链接会看到Welecome to nginx!我们可以继续访问一些不存在的路由,比如localhost:8080/index,同样会提示404。这个时候我们运行

    docker ps

    可以看到Docker容器的输出,就有内容了。 总结下刚才Docker做的事情:

    检查本地是否有指定的 nginx:latest 镜像(关于 latest 标签,后面会细讲),如果没有,执行第 2 步,否则直接执行第 3 步。本地没有指定镜像(Unable to find xxx locally),从 Docker Hub 下载到本地。根据本地的 nginx:latest 镜像创建一个新的容器,并通过 **-p(--publish**)参数建立本机的 8080 端口与容器的 80 端口之间的映射,然后运行其中的程序。Nginx 服务器程序保持运行,容器也不会退出。

    实例三:后台运行Nginx

    看上去很酷,不过像 Nginx 服务器这样的进程我们更希望把它抛到后台一直运行。按 Ctrl + C 退出当前的容器,然后再次运行以下命令:

    docker run -p 8080:80 --name my-nginx -d nginx

    注意到与之前不同的是,我们:

    加了一个参数 --name,用于指定容器名称为 my-nginx。加了一个选项 -d(–detach),表示 “后台运行”。

    {% blockquote %} 容器的名称必须是唯一的,如果已经存在同一名称的容器(即使已经不再运行)就会创建失败。如果遇到这种情况,可以删除之前不需要的容器(后面会讲解怎么删除)。 {% endblockquote %}

    Docker 会输出一串长长的 64 位容器 ID,然后把终端的控制权返回给了我们。我们试着访问 localhost:8080(服务器域名:8080),还能看到那一串熟悉的 Welcome to nginx!,说明服务器真的在后台运行起来了。

    那我们怎么管理这个服务器呢?就像熟悉的 UNIX ps 命令一样,docker ps 命令可以让我们查看当前容器的状态:

    docker ps

    输出结果是这样的: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5zj92rSg-1602064860480)(https://tothers.top1buyer.com/docker-1-5.png)]

    从这张表中,就可以清晰地看到了我们在后台运行的 Nginx 服务器容器的一些信息:

    容器 ID(Container ID)为 f104751ca7db(你机器上的可能不一样)。所用镜像(Image)为 nginx。运行命令 / 程序(Command)为 nginx -g 'daemon of…,这个是 Nginx 镜像自带的运行命令,暂时不用关心。创建时间(Created)为 an hour ago(一小时之前)。当前状态(Status)为 Up About an hout(已运行 超过一小时)。端口(Ports)为 0.0.0.0:8080->80/tcp,意思是访问本机的 0.0.0.0:8080 的所有请求会被转发到该容器的 TCP 80 端口。名称(Names)为刚才指定的 my-nginx。

    如果我们要让容器停下来,通过 docker stop 命令指定容器名称或 ID 进行操作即可,命令如下:

    docker stop my-nginx

    实例四:交互式运行

    运行以下命令,让我们进入到一个 Ubuntu 镜像中:

    docker run -it --name dreamland ubuntu

    可以看到我们加了 -it 选项,等于是同时指定 -i(–interactive,交互式模式)和 -t(–tty,分配一个模拟终端) 两个选项。以上命令的输出如下:

    这时我们已经在这个Ubuntu镜像中了,可以运行一些命令来看一下

    whoami ls

    按 Ctrl + D (或者输入 exit 命令)即可退出。你可以在 docker ps 的终端再次检查容器是否已经被关闭了。

    销毁容器

    我们刚才创建的 Docker 容器也只是用于初步探索,后续不会再用到。由于 Docker 容器是直接存储在我们本地硬盘上的,及时清理容器也能够让我们的硬盘压力小一些。我们可以通过以下命令查看所有容器(包括已经停止的):

    docker ps -a

    类似 Shell 中的 rm 命令,我们可以通过 docker rm 命令销毁容器,例如删除我们之前创建的 dreamland 容器:

    docker rm dreamland # 或者指定容器 ID,记得替换成自己机器上的 # docker rm f104751ca7db(你机器上的可能不一样)。

    但如果我们想要销毁所有容器怎么办?一次次输入 docker rm 删除显然不方便,可以通过以下命令轻松删除所有容器:

    docker rm $(docker ps -aq)

    docker ps -aq 会输出所有容器的 ID,然后作为参数传给 docker rm 命令,就可以根据 ID 删除所有容器啦。

    删除运行中的容器

    docker rm -f dreamland

    同样的,我们可以删除所有容器,无论处于什么状态:

    docker rm -f $(docker ps -aq)

    容器化第一个应用:开启筑梦之旅

    在之前的步骤中,我们体验了别人为我们提前准备好的镜像(例如 hello-world、nginx 和 ubuntu),这些镜像都可以在 Docker Hub 镜像仓库中找到。在这一步,我们将开始筑梦之旅:学习如何容器化(Containerization)你的应用。

    运行以下命令来获取代码,然后进入项目:

    git clone -b start-point https://github.com/tuture-dev/docker-dream.git cd docker-dream

    如果没有安装git,可以运行

    yum install git

    来安装,也可以到GIT官网来查看如何安装你所对应的平台。

    在这一步中,我们将容器化这个用 React 编写的前端应用,用 Nginx 来提供前端页面的访问。

    什么是容器化

    什么是容器化:

    编写代码:我们已经提供了写好的代码。构建镜像。创建和运行容器:通过容器的方式运行我们的应用。

    构建镜像

    构建 Docker 镜像主要包括两种方式:

    手动:根据现有的镜像创建并运行一个容器,进入其中进行修改,然后运行 docker commit 命令根据修改后的容器创建新的镜像。自动:创建 Dockerfile 文件,指定构建镜像的命令,然后通过 docker build 命令直接创建镜像。

    准备工作

    我们先把前端项目 client 构建成一个静态页面。确保你的机器上已经安装 Node 和 npm(点击这里下载,或使用 nvm),然后进入到 client 目录下,安装所有依赖,并构建项目:

    cd client npm install npm run build

    如果安装node和npm出现问题的可以看下我之前的这篇文章Linux安装Node。

    等待一阵子后,你应该可以看到 client/build 目录,存放了我们要展示的前端静态页面。

    创建 Nginx 配置文件 client/config/nginx.conf,代码如下:

    server { listen 80; root /www; index index.html; sendfile on; sendfile_max_chunk 1M; tcp_nopush on; gzip_static on; location / { try_files $uri $uri/ /index.html; } }

    上面的配置大致意思是:监听 80 端口,网页根目录在 /www,首页文件是 index.html,如果访问 / 则提供文件 index.html。

    创建 Dockerfile

    然后就是这一步骤中最重要的代码:Dockerfile!创建 client/Dockerfile 文件,代码如下:

    FROM nginx:1.13 # 删除 Nginx 的默认配置 RUN rm /etc/nginx/conf.d/default.conf # 添加自定义 Nginx 配置 COPY config/nginx.conf /etc/nginx/conf.d/ # 将前端静态文件拷贝到容器的 /www 目录下 COPY build /www

    可以看到我们用了 Dockerfile 中的三个指令:

    FROM 用于指定基础镜像,这里我们基于 nginx:1.13 镜像作为构建的起点。RUN 命令用于在容器内运行任何命令(当然前提是命令必须存在)。COPY 命令用于从 Dockerfile 所在的目录拷贝文件到容器指定的路径。

    现在可以来构建我们的镜像了,运行以下命令:

    # 如果你已经在 client 目录中 #(注意最后面有个点,代表当前目录) docker build -t dream-client . # 如果你回到了项目根目录 docker build -t dream-client client

    可以看到我们指定了 -t(–tag,容器标签)为 dream-client,最后指定了构建容器的上下文目录(也就是 当前目录 . 或 client)。

    运行以上的命令之后,你会发现:

    Sending build context to Docker daemon 289.4MB

    接着运行了一系列的 Step(4 个),然后提示镜像构建成功。

    为什么这个构建上下文(Build Context)这么大?因为我们把比 “黑洞” 还 “重” 的 node_modules 也加进去了!(忍不住想起了下面这张图)

    Docker 提供了类似 .gitignore 的机制,让我们可以在构建镜像时忽略特定的文件或目录。创建 client/.dockerignore 文件(注意 dockerignore 前面有一个点):

    node_modules

    再次运行构建命令:

    docker build -t dream-client .

    可以看到这次只有1.217MB,而且速度也明显快了很多.

    运行容器

    终于到了容器化的最后一步 —— 创建并运行我们的容器!通过以下命令运行刚才创建的 dream-client 镜像:

    docker run -p 8080:80 --name client -d dream-client

    与之前类似,我们还是设定端口映射规则为 8080:80,容器名称为 client,并且通过 -d 设置为后台运行。然后访问 localhost:8080(老样子–服务器域名:8080): 可以看到如图所示的页面,表示容器运行成功.

    关于镜像标签

    在刚才的实战中,你也许已经注意到在拉取和构建镜像时,Docker 总是会为我们加上一个 :latest 标签,这个 :latest 的含义便是 “最新” 的意思。和软件的版本机制一样,镜像也可以通过标签实现 “版本化”。

    实际上,我们完全可以在拉取或构建镜像时指定标签(通常被认为是一种好的做法):

    docker pull nginx:1.13 docker build -t dream-client:1.0.0

    还可以给现有的镜像打上标签:

    # 把默认的 latest 镜像打上一个 newest 标签 docker tag dream-client dream-client:newest # 甚至可以同时修改镜像的名称和标签 docker tag dream-client:1.0.0 dream-client2:latest

    可以看到,标签未必一定是版本,还可以是任何字符串(当然最好要有意义,否则过了一阵子你也不记得这个打了这个标签的容器有什么作用了)。

    关于 Dockerfile

    Dockerfile 实际上是默认名称,我们当然可以取一个别的名字,例如 myDockerfile,然后在构建镜像时指定 -f(–file)参数即可:

    docker build -f myDockerfile -t dream-client .

    这里举两个经典的使用场景:

    例如在 Web 开发时,分别创建 Dockerfile.dev 用于构建开发镜像,创建 Dockerfile.prod 构建生产环境下的镜像;在训练 AI 模型时,创建 Dockerfile.cpu 用于构建用 CPU 训练的镜像,创建 Dockerfile.gpu 构建用 GPU 训练的镜像。

    最后

    这篇文章是我跟着图灵社区的流程走了一遍所记录的过程,点击这里查看图灵社区

    Processed: 0.015, SQL: 8