docker基本命令的使用

01. 使用容器运行Hello World

使用命令行运行以下命令,此命令将启动一个ubuntu的容器并在其中输出 Hello World文本,执行完毕后,容器自动退出。

02. 与容器进行交互

使用命令行运行以下命令,此命令将启动一个ubuntu容器并在其中运行bash交互命令行界面,你可以尝试运行pwd,ls,ps等命令查看容器内环境,就如同远程操作一台服务器一样。

03. 在容器中运行持续任务并管理容器生命周期

使用命令行运行以下命令,此命令将启动一个ubuntu容器并在其中持续运行echo hello world,启动后容器会持续输出hello world文本。

注意当你运行以上命令后,命令行直接退出并没有持续输出hello world文本,这是因为我们使用了-d参数,这时容器在后台运行,你可以通过docker logs命令获取容器内的日志输出,注意替换c3a2为你的容器ID的前四位,如下:

为了查看当前正在运行状态的容器,你可以使用docker ps命令,如下:

你也可以查看到那些没有在运行状态的容器,使用docker ps -a命令,如下:

注意以上出了第一个容器正在运行意外,另外2个ubuntu容器都已经停止,但是容器仍然存在。你可以理解为他们是没有被运行中的应用,而应用的文件存在于你的docker环境中。

现在,你可以通过docker stop {id}命令来停止正在运行的容器,如下:

然后,通过docker rm {id}命令来删除所有未运行的容器,(注意将id替换成你自己的容器ID的前四位)如下:

也可以通过这个命令自动枚举所有容器并停止,删除:

04. 运行web应用并通过浏览器访问

使用命令行运行以下命令

完成后打开浏览器并导航到 http://localhost:8080,你应该可以看到类似以下页面

注意以上命令与之前的最大区别在于使用了-p参数来映射网络端口,这样我们就可以通过容器主机的8080端口来访问容器的80端口,类似于实现了一个简单的NAT。你也可以使用-P(大写)参数来让docker自动分配主机端口,这样可以避免我们手动分配端口造成冲突。

你可以尝试使用以上实验中的docker logs和docker ps等命令查看此正在运行容器的状态和其中的web服务器所输出的日志,如下

运行以下命令式请注意替换dda5为你自己的容器id,同时可以尝试刷新浏览器看到日志的实时输出

另外,你还可以使用docker top {id}命令查看容器中的进程列表

或者通过 docker exec 命令直接进入容器进行操作

小结

至此,你应该已经基本掌握了运行容器的主要命令,下一节中,我们将尝试完成一个新的容器镜像的构建并运行我们自己构建的容器镜像。

0

MySQL 官方Docker镜像的使用

Docker镜像是用来创建容器的,我们可以基于官方提供的镜像或自已构建的镜像来创建容器。https://hub.docker.com/_/mysql/是Docker及MySQL提供、维护的一个官方镜像,我们可以基于该镜像构建自己的MySQL数据库镜像,也可以直接使用这个镜像创建MySQL数据库容器。下面介绍MySQL 官方Docker镜像的使用。

MySQL 官方Docker镜像的使用
MySQL 官方Docker镜像的使用

1. 启动一个mysql服务器实例

使用mysql镜像创建或启动MySQL容器时,可以先将镜像下载到本地:

也可以直接使用以下命令来启动MySQL实例:

这样,我们就创建了一个名为sww-mysql的MySQL数据库服务器容器实例。在创建数据库时,通过环境变量MYSQL_ROOT_PASSWORD设置数据库的root密码,还通过5.7标签指定了所使用的镜像版本。

容器创建完成后,可以通过docker ps命令看到所创建的MySQL容器实例:

2. 在其它Docker容器应用中连接MySQL

在这个镜像中,导出的是MySQL的标准端口3306。这样我们就可以在需要访问MySQL服务器的容器中,使用--link参数通过容器链接的方式,将MySQL服务器容器实例连接到包含了需要使用MySQL的应用容器中。

使用容器连接的示例如下:

注意:以上示例中的application-that-uses-镜像并不存在,仅为操作演示,下同。

除了进行容器连接的方式在其它容器中访问MySQL服务器容器外,还可以通过以下两种方式访问MySQL数据库服务器容器:

  • 在创建MySQL服务器容器实例时通过-p-P参数将数据库服务器端口映射到宿主机,再直接通过宿主机进行访问。这种方式较为简单,但需要向外暴露数据库端口。
  • 能过Docker网络(Networking)进行连接。这种方式操作较为复杂,但更为灵活,可以适用于更加复杂的网络环境。

3. MySQL命令行客户端连接MySQL

在前面创建的MySQL服务器容器中,我们并没有向外暴露访问端口,我们可以通过以下方式启动命令行客户端,并基于命令行客户端对数据库服务器进行管理。

运行另一个MySQL交互式容器,该容器会在运行后启动mysql命令行客户端:

如果需要通过非Docker的方式,或远程访问MySQL服务器容器,就可以在创建容器时通过-p-P与宿主机进行端口绑定,之后就可以像普通MySQL服务器那样进行访问或操作。

4. 在Shell中访问容器及日志查看

docker exec命令使我们可以在Docker容器内部执行命令,我们可以通过以下方式与mysql容器建立一个shell连接:

而MySQL服务器日志,可以直接通过Docker容器日志访问(实时日志查看可以添加-f参数):

5. 使用自定义MySQL配置文件

默认情况下,MySQL的启动配置文件是/etc/mysql/my.cnf,而/etc/mysql/conf.d目录下的存在任何.cnf格式的文件时,都会使用该文件中配置项替换默认配置。

因此,如果要使用自定义配置,可以在宿主机创建一个配置文件,然后在创建容器时通过-v参数,以数据卷的方式将自定义配置挂载到mysql容器的/etc/mysql/conf.d目录下。

如,在宿主机中存在/my/custom/config-file.cnf配置文件,这时就可以通过以下方式启动MySQL容器:

以上示例会启动一个名为sww-mysql的MySQL服务器容器,该文件启动时会同时使用/etc/mysql/my.cnf/etc/mysql/conf.d/config-file.cnf中的配置。

不使用cnf文件的配置方式

除使用.cnf文件进行配置外,还可以在启动容器通过参数的形式将配置传递给mysqld

如,启动一个MySQL服务器容器,并使用UTF-8(utf8mb4)格式的表编码:

详细配置参数可以通过以下命令查看:

6. 环境变量

当启动mysql容器时,我们可以向docker run命令传入一或多个环境变量来调整MySQL实例的配置。可设置的环境变量有:

  • MYSQL_ROOT_PASSWORD:必须。用于设置MySQLroot用户的密码
  • MYSQL_DATABASE:可选。用于指定镜像启动容器时要创建的数据库。如果提供了用户/密码,则会将该用户做为此数据库的超级用户。
  • MYSQL_USERMYSQL_PASSWORD:可选。用于创建一个新用户并设置密码。
  • MYSQL_ALLOW_EMPTY_PASSWORD:可选。设置为yes时,则可以使用空密码登录
  • MYSQL_RANDOM_ROOT_PASSWORD:可选。设置为yes时会为root用户设置一个随机密码(使用pwgen),所生成的随机密码会被输出到stdout
  • MYSQL_ONETIME_PASSWORD:可选。为root用户指定一个一次性密码,该密码会在用户首次登录时强制修改

7. 关于数据存储

在使用 mysql镜像创建MySQL容器时,数据库数据存储可能会有以下两种方式:

  • 数据卷容器:使用Docker默认的数据管理方式来管理数据库的数据存储,在这种方式下,数据库文件会被写入数据库的内部。这种方式对于用户非常简单,缺点是很在宿主机上找到所存储的数据。
  • 外部数据卷:在宿主机创建一个数据目录,再将数据目录挂载到容器内部。这种方式可以很方便的在宿主机上找到并进行数据管理,但需要确保数据目录的存在。

当使用外部数据卷时,假在宿主机有/my/own/datadir目录,我们可以像下面这样启动mysql容器,并将目录挂载到容器内:

其中,-v /my/own/datadir:/var/lib/mysql是数据卷的挂载,表示将宿主机的/my/own/datadir目录挂载到容器内的/var/lib/mysql目录。这个目录是MySQL的默认数据目录,当使用自定义配置时,应该也做相应的修改。

数据库备份

在非Docker环境下使用的MySQL备份工具,大多数在容器环境下仍然可用,只要其能访问mysqld服务器即可。

下面是一个通过docker exec来对mysql容器中的数据库执行备份的示例:

0

Spring Boot项目使用Docker和Kubernetes(k8s)进行容器化部署

Spring Boot项目的结构

项目名称是Test

  1. 项目根据环境不同需要读取不同的application.yml
  2. 项目使用logback作为日志工具,需要读取一个logback-spring.xml的配置文件。
  3. 项目还需要读取一个properties文件。
  4. 为方便,所有Kubernetes资源均在default namespace下。
namespace

Kubernetes的许多资源对象都隶属于某个namespace,namespace是对资源的逻辑划分,不同namespace下的资源可以做到简单隔离。

准备工作

镜像

针对项目jar包,我们需要将其打成一个Docker镜像,而Dockerfile就是打包过程的指导文件,类似于make过程中的Makefile

jar->Docker镜像

以下是Dockerfile的内容。


  1. FROM表示要生产的镜像的基础镜像,我们使用jdk8。
  2. VOLUME表示定义一个匿名卷,也可以理解为创建一个目录,这里的/tmp是由于tomcat的需要。
  3. ADD表示将项目编译后的jar包拷贝到镜像里,默认为根目录/
  4. ENTRYPOINT表示入口点,即容器启动时执行的命令,通过上述组合,实际执行的命令为:java -Djava.security.egd=file:/dev/./urandom -jar -Dspring.config.location=/etc/config/application.yml -Dlogging.config=/etc/config/logback-spring.xml -DconfPath=/etc/config /test.jar
    注意这里的配置路径/etc/config还不存在,下文中会创建和用到。

配置

Kubernetes ConfigMap

ConfigMap可以用来保存单个的键值对,也可以保存配置文件。

配置文件->ConfigMap

针对项目配置,需要做的改造就是把配置文件(应用、日志、业务)转化成ConfigMap对象,从而让Kubernetes化后的应用能够读取。

以下是test-config.yml的内容。


  1. 注意配置文件按照yaml规范缩进。
  2. data属性里记录实际的配置,本质上仍是键值对,如第一个数据的key为application-yml,内容为其配置内容。

应用部署定义

Kubernetes Deployment

Deployment是一种控制容器组的对象,在Deployment中定义一个期望的容器组的数量,Deployment在创建后会维持这个数量,当数量少于期望时会新建容器组,反之会停止超额的容器组。

部署->Deployment

针对本项目,对应的Deployment配置如下。

test-deployment.yml内容如下。


  1. replicas即为此Deployment期望的容器组的数量。
  2. metadata.labels用于跟下文中的Service对接。
  3. spec.selector.matchLabels与容器组的spec.template.metadata.labels对接。
  4. spec.template.spec.volumes定义了一些卷,name为卷名。
    • 如果定义了configMap属性,则items属性的key对应上文中ConfigMap对象的名称,path则为要输出的文件,如第一个item的行为是读取ConfigMap对象test-config的第一个数据的内容(key=application-yml),并将其保存为application.yml配置文件。
    • 如果定义了hostPath属性,则是宿主机上的同名目录,如此处将容器日志输出到宿主机的/var/log/test路路径。
  5. spec.template.spec.containers定义了容器组中的容器,包括容器名、镜像、容器暴露的端口,以及要挂载的卷,在volumeMounts中,name为上述卷名,mountPath为挂载路径,从而容器内部存在/etc/config路径,且可以读取到上述配置文件。

服务定义

Kubernetes Service

默认情况下,Kubernetes集群内的容器是不能被集群外访问的。此时我们需要将应用连接到Service,Service可以对集群内部暴露,也可以对外暴露宿主机端口,还能通过LB VIP暴露服务。

外部访问->Service

针对本项目,对应的Service配置如下。

test-service.yml内容如下。


  1. spec.selector用于连接容器组,与上文中Deployment定义的容器组的labels对应。
  2. spec.type定义Service的暴露方式,NodePort为对集群外暴露,用户通过宿主机端口访问应用,即:
    • 用户->宿主机IP:30777->Service:7777->容器:7777

部署工作

编译jar包

不论使用Maven还是Gradle,生成jar包,此处不细说。

生成Docker镜像

使用以下命令生成Docker镜像,当然,前提是生成镜像的机器上需要有基础镜像openjdk:8-jdk-alpine


同时,需要让所有Kubernetes的Node能获取到该镜像,有两种途径:

  1. 将该镜像打包并在所有Node上加载。

  2. 将该镜像推送到所有Node均能访问的镜像仓库里。
创建Kubernetes资源

分别创建ConfigMap、Deployment、Service。


验证

查看资源对象是否正常。


访问服务。


+2

使用 docker-compose 打包部署多个应用

准备工作

准备部署两个项目,一个是 web 站点项目,一个是爬虫的后台应用项目。

  1. 两个项目的 jar 包,分别为 app.jar,spider.jar
  2. 两个应用都依赖 redis 和 mysql
  3. mysql 初始化需要的 sql 文件

docker file 文件

docker file 是 使用 docker 部署应用的命令。 具体的命令可以参考 Docker 命令.

由于是两个文件,所以需要两个不同的 Dockerfile .具体的 build 的内容如下:

Dockerfile web 的 build 文件

爬虫的文件

Compose 文件

最终文件的目录

如何访问 DB 和 Redis

由于 docker compose 会自动创建一个虚拟的内网环境,所以在访问 MySQL 和 Redis 只需要使用镜像的名称即可解析到对应的域名。

最后直接执行 docker-compose执行打包部署。

0

使用Dockerfile为SpringBoot应用构建Docker镜像

Dockerfile常用指令

ADD

用于复制文件,格式:

示例:

ENTRYPOINT

指定docker容器启动时执行的命令,格式:

示例:

ENV

用于设置环境变量,格式:

示例:

EXPOSE

声明需要暴露的端口(只声明不会打开端口),格式:

示例:

FROM

指定所需依赖的基础镜像,格式:

示例:

MAINTAINER

指定维护者的名字,格式:

示例:

RUN

在容器构建过程中执行的命令,我们可以用该命令自定义容器的行为,比如安装一些软件,创建一些文件等,格式:

示例:

使用Dockerfile构建SpringBoot应用镜像

编写Dockerfile文件

使用maven打包应用

在IDEA中双击package命令进行打包:

打包成功后展示:

将应用jar包及Dockerfile文件上传到linux服务器:

在Linux上构建docker镜像

在Dockerfile所在目录执行以下命令:

输出如下信息:

查看docker镜像:

展示图片

运行mysql服务并设置

1.使用docker命令启动:

2.进入运行mysql的docker容器:

3.使用mysql命令打开客户端:

4.修改root帐号的权限,使得任何ip都能访问:

5.创建mall数据库:

6.将mall.sql文件拷贝到mysql容器的/目录下:

7.将sql文件导入到数据库:

运行mall-tiny-docker-file应用

访问接口文档地址http://192.168.3.101:8080/swagger-ui.html:

0