版权声明:可以任意转载,转载时请标明文章原始出处-ScriptShi 前言 Docker 处于了解并使用的情况,但使用也是在 DevOps 下使用的,只有一个宏观的了解,因此对 Docker 的各种具体使用也不熟悉,所以决定探索一下,如果内存可以的话,将自己的云服务器全部 Docker 化。 试验机介绍 本是在自己的虚 ..

我的 docker 探索之路

本贴最后更新于 496 天前,其中的信息可能已经东海扬尘

版权声明:可以任意转载,转载时请标明文章原始出处-ScriptShi

前言

Docker 处于了解并使用的情况,但使用也是在 DevOps 下使用的,只有一个宏观的了解,因此对 Docker 的各种具体使用也不熟悉,所以决定探索一下,如果内存可以的话,将自己的云服务器全部 Docker 化。

试验机介绍

本是在自己的虚拟机里,但是感觉不是很爽,虚拟机设置个 16G 内存,8C 跑个小 Docker,对 CPU 和内存的使用不能真的查看,想在生产环境里直接看一下效果。

服务器是阿里云的,今天刚买的一年的学生机,1C 2G 40G-SSD 1M,如下:

安装的操作系统是 CentOS 7.3

安装 Docker

yum update
curl -fsSL https://get.docker.com/ | sh
service docker start 

设置开机启动:systemctl enable docker

在阿里云的“开发者平台”上进行换源,换成国内镜像,提高速度(脚本中的 xxxxx 是个人独有的,由阿里云生成的)。

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxxxxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker 

测试 helloworld:docker run hello-world

常见 Docker 命令

列一下 Docker 常用的操作,做个纪念吧。重点会用启动/停止/删除、看日志、进容器里就可以了。

安装 MySQL

安装最新版的 MySQL:同时设置容器名字,数据卷分离, 暴露端口,设置密码,后台启动,重启策略,远程镜像名字(不带版本号默认最新版)

docker run --name mysql -v /data/mysql:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=你的默认密码 -d --restart=unless-stopped mysql:5.6.35

常用的几个就是我安装 MySQL 时候用到的这些。

进入 Docker 容器内部:docker exec -it mysql bash

进入 MySQL 的 shell 界面:mysql -uroot -p你的mysql用户密码

想起来以前安装 MySQL 好麻烦呀!Docker 使我感到开心。

在自己电脑上连接远程服务器,进行远程连接测试(首先你需要知道这是不安全的和生产环境绝对不允许的,其次你需要打开防火墙)

如下,测试成功。

SpringBoot 服务的部署

我写了个只有一个 hi 的 Web 服务:https://github.com/xjtushilei/jenkins-test.git

并写了一个简单的 Dockerfile(下一节简单讲讲 dockerFile 的书写)

FROM openjdk:8-jdk-alpine
RUN mkdir -p /root/workspace/project
WORKDIR /root/workspace/project
COPY build/libs/*.jar app.jar
#RUN set -ex && ./gradlew build
#RUN cp build/libs/*.jar app.jar

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/root/workspace/project/app.jar"] 

其实三行就可以搞定,多写的主要是为了练习。

我分别尝试了在 Docker 里进行构建和在 Docker 外。(具体采取哪种方式要看 DevOps 了,自己开发的话还是 Docker 外吧,不然每次从 maven 中央仓库拉 jar 包很难受,即便换为国内的源;如果在 Docker 内构建的话,可以省略外部代码编译这一步,直接从代码到 Docker 镜像,但是会延长发布时间)

我们先把代码拉下来,

yum install git # 新机器,发现没装git,尴尬
git clone https://github.com/xjtushilei/jenkins-test.git
cd jenkins-test 

在代码主目录下:

  1. 用 gradle 编译打包代码,会生成可运行的 jar
  2. 构建 Docker 镜像
  3. 运行 Docker 镜像
yum install java-1.8.0-openjdk  java-1.8.0-openjdk-devel # 新机器,发现没装jdk,尴尬
./gradlew  build
docker build -t hi . 

如下所示:构建我自己的 Docker 成功了。

直接非后台运行:docker run -p 8080:8080 hi就看到了如下熟悉的界面:

远程测试成功:

到现在为止,我们也学会了如何发布自己的 Docker。我这里推荐使用阿里云的容器镜像服务,特别方便!不用自己拉 pull 代码,直接用他们的服务检测 Git 里代码的变化,动态更新镜像。

Dockerfile 大致流程

如此反复执行……

在构建过程中每次生成一层新的镜像的时候这个镜像就会被缓存。即使是后面的某个步骤导致构建失败,再次构建的时候就会从失败的那层镜像的前一条指令继续往下执行。

DockerFile 的书写

DockerFile 分为四部分组成:基础镜像信、维护者信息、镜像操作指令和容器启动时执行指令

#第一行必须指令基于的基础镜像
From ubutu

#维护者信息
MAINTAINER docker_user  docker_user@mail.com

#镜像的操作指令

RUN apt-get update && apt-get install -y ngnix 
RUN echo "\ndaemon off;">>/etc/ngnix/nignix.conf

#容器启动时执行指令
CMD /usr/sbin/ngnix 

下面讲一下 DockerFile 常见的指令

FROM

格式为 FROM 或 FROM:。

第一条指令必须为 FROM 指令。并且,如果在同一个 Dockerfile 中创建多个镜像时,可以使用多个 FROM 指令(高版本 Docker 建议搭配 as 使用)。

MAINTAINER

格式为 MAINTAINER,指定维护者信息。

RUN

格式为RUN 或 RUN["executable", "param1", "param2"]

前者将在 shell 终端中运行命令,即/bin/sh -c;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如RUN ["/bin/bash", "-c", "echo hello"]

每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\来换行。

CMD

支持三种格式

指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

EXPOSE

格式为EXPOSE [...]

告诉 Docker 服务端容器暴露的端口号,供互联系统使用。

这里仅仅是告诉,如果想给宿主机调用的话,需要 run 的时候-p 进行端口转发。

ENV

格式为ENV 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。

例如

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH 

ADD

格式为ADD

该命令将复制指定的到容器中的。 其中可以是 Dockerfile 所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。

COPY

格式为 COPY。

复制本地主机的(为 Dockerfile 所在目录的相对路径)到容器中的。

当使用本地目录为源目录时,推荐使用 COPY。这是和 ADD 的主要区别。

ENTRYPOINT

两种格式:

配置容器启动后执行的命令,并且不可被 Docker run 提供的参数覆盖。

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

VOLUME

格式为VOLUME ["/data"]

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

USER

格式为 USER daemon。

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

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用 gosu,而不推荐 sudo。

WORKDIR

格式为 WORKDIR /path/to/workdir。

为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。

可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd 

则最终路径为/a/b/c。

Docker 的其他注意事项

  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包括系统。

    225 引用 • 412 回帖 • 634 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    635 引用 • 831 回帖 • 700 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    161 引用 • 177 回帖 • 565 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    605 引用 • 1209 回帖 • 825 关注
9 回帖   
请输入回帖内容...
  • louishe  

    这个探索很有意义, 很棒!

  • bug123  

    学到了

  • sunying52xx  

    可以的 学习了

  • gxphahaha  

    嗯嗯

  • oswuhan  

    标准入门姿势

  • 54FCS  

    一脸懵逼😂

  • caijunyi  

    好帖!我已经收藏!!!

  • shuiniu  

    学生,学多点

  • skipper  

    我也正在学 Docker, 哈哈

请输入回帖内容 ...