Docker实战-从入门到跑路

领导:“你会Docker吗?”我寻思,Docker是什么?含糊回道:“嗯……应该不会。”领导:“去学学。”我面露难色。领导:“我朋友公司那个月薪4K的开发,什么分布式,大数据,阿里云,百度云,信口……拈来!你要对得起你8K的工资!”我无言以对,无法反驳,无法反抗。

本人使用的环境是Ubuntu 16.04,64位系统。

首先了解下Docker。百度百科:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

个人理解,类似镜像和虚拟机。什么是虚拟机?自行百度。装个vmvare或者virtualbox试试就知道了。

传统的部署应用:购买服务器,根据不同的操作系统安装应用运行环境,如JDK,Tomcat,mysql等等。上传文件,一堆配置,费神费力。

使用Docker部署应用:购买服务器,安装Docker环境,编写Dockerfile,创建Docker镜像,启动Docker容器。加个Jenkins做一键部署更方便

在初学Docker时,最让人害怕的可能是Dockerfile编写,我刚接触的时候也被吓到了,后来发现其实没想象的那么难。不要恐惧未知。

Docker相当于一个虚拟机,Dockerfile则相当于告诉虚拟机按照步骤执行哪些指令。很多情况下,我们并不需要写Dockerfile,Docker仓库里已有专业人士做好了Docker镜像,我们只需要拿来用就行了。

docker安装

Docker安装我们选择简单的方式,下载Docker官方的脚本,执行。复杂的方式请自行百度。

						curl -fsSL get.docker.com -o get-docker.sh
						sh get-docker.sh

脚本执行完后,一般来说docker安装成功了。执行以下指令测试docker是否可用

docker -v

有些系统可能会提示:Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?(我在阿里云大陆服务器经常遇到)

执行以下指令:

						systemctl daemon-reload
						systemctl restart docker.service


docker-compose安装

装docker-compose是为了方便管理docker容器,每次启动docker容器输入一大串参数相信你也觉得麻烦。

请去 https://github.com/docker/compose/releases 获取最新版本的下载脚本。我这里以我经常用的1.24.1为例

执行以下命令:

						curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
						chmod +x /usr/local/bin/docker-compose

运行可能会报错,手动下载相应的docker-compose文件,上传到服务器的 /usr/local/bin/docker-compose 目录

执行 docker-compose -v 测试是否安装成功

docker安装mysql5.7

先介绍下Dockerfile,docker容器,docker-compose之间的关系

Dockerfile用于构建镜像,镜像用于创建容器(虚拟机),docker-compose用于配置容器启动命令。

先有镜像再有容器,一个镜像可以创建多个容器,容器的名字不能一样,各个容器互不干扰。就像装系统的小哥拿个盗版win10光碟,可以给无数台电脑装系统一样。盗版光碟是镜像,电脑是容器。再打个粗俗的比方:给你一头母猪,你能创造一个族群。

完整的创建到启动容器流程,需要先编写Dockerfile,创建镜像,再在docker run 命令后面加一大串参数灵活配置容器。容器启动可能会附带多个命令参数,比如mysql可以自定义数据文件目录,通信端口等。

为了简化过程(偷懒),减少记忆量,可以编写docker-compose配置文件,实现快速部署应用。


下面以mysql 5.7为例演示docker从入门到跑路

领导:“昨天给了你一天时间学习,进展怎么样了。”我内心慌的一匹,道:“略懂一二。”领导:“怎样用Docker部署mysql 5.7。”我打开word文档,以领导看不清的速度迅速划动:“如此如此,这般这般……”领导:“说人话!”


首先,搜索并下载指定版本的mysql镜像

docker search mysql

也可以进入https://hub.docker.com/ ,搜索mysql,进入mysql官方镜像页面。

Supported tags and respective Dockerfile links 下面的是mysql的各版本号,根据项目选择需要的版本pull到本地仓库。

下载镜像:docker pull 镜像名:版本号

docker pull mysql:5.7

版本号可以不写,如:docker pull mysql,不加版本号下载的是最后一个版本(latest)


查看本地仓库镜像列表

docker image ls

Repository 是镜像名,Tag是镜像的版本号,IMAGE_ID是镜像ID

删除本地仓库镜像:docker image rm 镜像ID(IMAGE_ID)

一般来说,镜像ID取前四位即可,比如我要删除mysql:latest,执行:docker image rm e1d7

如果无法删除,可能是关联了容器,需要先删除容器,才能删除镜像


启动mysql容器:

docker run -d --name mysql -v /usr/local/docker/mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql:5.7

--name:容器名

-d:后台启动

-v:将容器中mysql的数据目录映射到宿主机。-v 宿主机目录:容器内目录。如果想映射多个目录,多加几个-v。此方式同样适用-e,-p等参数

-e:传入参数,这里是设置mysql的访问密码

-p:将容器的3306端口映射到宿主机的3306端口。docker容器相当于虚拟机,默认情况下它有自己独立的虚拟网卡和IP,它的3306端口是它自己的,不是宿主机的,所以要做端口映射

mysql:5.7是镜像名。如果镜像不存在,docker会自动pull该镜像。

dockerhub的官方镜像下面一般有使用说明(英文的),可以参照使用说明启动容器。相对于传统的安装mysql来说,这种方式简单的多。


曾经遇到过,mysql安装好后,无法远程连接操作mysql(现在没遇到过这问题)。这和在liunx装mysql无法远程连接是一个道理,需要打开mysql的远程连接权限。

可以在启动容器的时候使用 -v 替换容器的相关配置文件,或者,进入docker容器

docker exec -it mysql bash

登录mysql

mysql -u root -p

输入密码,登录mysql,执行以下mysql语句

grant all on *.* to root@'%' identified by '远程连接的密码' with grant option;


FLUSH PRIVILEGES;

执行以上操作后,你可以用“远程连接的密码”连接mysql。这时候mysql有两个密码,一个是本地连接的密码(-e MYSQL_ROOT_PASSWORD设置的密码),一个是远程连接的密码


这样生成的mysql容器,宿主机部署的项目是无法通过localhost或者127.0.0.1访问的。就像你在win10中用vm装了个win7,win10上运行的项目无法通过localhost连接win7中的数据库。

为了能让项目使用localhost访问mysql,我们可以让mysql容器和宿主机用同一个网络

你可以在启动命令加上 --net=host,即:

docker run -d --name mysql -v /usr/local/docker/mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 --net=host mysql:5.7

这样你的应用就能像访问本机mysql一样访问mysql容器了。

--net=host即让容器与宿主机共用网络,Docker网络有bridge(默认),host(与主机共用IP和端口),none(关闭容器网络),overlay(集群)。请自行百度了解。


查看运行的容器

docker ps

查看所有容器(包含已停止的)

docker ps -a

CONTAINER ID:容器ID

IMAGE_ID:镜像名

STATUS:容器状态

NAMES:容器名,由--name参数指定


停止容器:docker stop 容器ID,比如要停止mysql,执行:docker stop a7df

启动容器:docker start 容器ID

查看容器日志:docker logs -f -t --tail 行数 容器ID/容器名。查看docker_file的日志:docker logs -f -t --tail 100 c38a (建议用容器名)

查看容器详细信息:docker inspect 容器名

进入容器终端:docker exec -it 容器ID /bin/bash

docker-compose启动mysql

按照上面的方法创建好容器,还会有一些问题,比如数据库时间不对等,这些都可以通过加参数解决。为了不在下次使用的时候再去找这些参数,我们可以编写docker-compose文件。

随便找一个地方,创建 docker-compose.yml文件。

vi docker-compose.yml

输入以下文本:

						version: "2" #表示本docker-compose文件使用的是 version 2 file,3和2的写法有差别
						services:
						  mysql1: #容器名
							image: mysql:5.7 #镜像名
						   # network_mode: "host" #网络模式
							restart: always #容器异常崩溃后自动重启
							volumes: #映射目录
							  - "/usr/local/docker/mysqldata1:/var/lib/mysql"
							environment: #参数
							  - TZ=Asia/Shanghai   #使用北京时间
							  - MYSQL_ROOT_PASSWORD=12345678   #设置密码
							ports : #端口,因为3306已被另一个mysql使用,这个容器用8080
							  - "8080:3306"

保存并退出,执行

docker-compose build

再执行

docker-compose up -d

mysql容器启动成功。特别要注意yml文件的格式,分号后面必须有一个空格。子节点和父节点偏移一个 Tab或者2个空格。

如果要停止容器,除了使用docker stop,还可以使用 docker-compose stop mysql1

编写一个Dockerfile

以openjdk:8-jdk-slim为基础镜像,创建一个同时运行两个springboot项目的镜像。同时运行两个项目用到了supervisor,看日志很麻烦,建议一个容器只运行一个项目。

建议查看Docker的详细文档了解指令含义。

						#指定操作的镜像
						FROM openjdk:8-jdk-slim

						#维护者信息
						MAINTAINER liuming "842417019@qq.com"

						#安装supervisor
						RUN apt-get update \
								&& apt-get install -y supervisor \
								&& mkdir -p /var/log/supervisor

						#复制文件到容器
						COPY xym-gateway.jar /usr/app/
						COPY xym-static.jar /usr/app/
						COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
								
						#暴露端口
						#gateway
						EXPOSE 8001
						#static
						EXPOSE 8002

						#执行supervisord
						CMD ["/usr/bin/supervisord"]

指定基础镜像,安装相关软件,再将项目复制到指定目录,运行项目。这和我们部署项目的步骤何其相似。RUN运行的,其实就是一系列liunx shell指令,多个指令以特定的格式隔开

学习更多Docker知识,可去网上查阅 Docker技术入门与实战 这本书

跑路

我:“领导,我有点事,想和你说下。”领导:“你说。”我:“最近房租涨了,物价也涨了,我楼下那家沙县的蛋炒饭涨到10块……”领导打断了我:“你堂堂七尺男儿,要为五斗米折腰?你现在还年轻,正是学习的好时候!你问问,哪家公司能给你8K月薪,还能让你学这么多知识!”我:“道理我都懂,加点吧。”领导:“我们公司现在正在创业阶段,现在日子虽然苦了点,等以后飞黄腾达了,你就是公司元老!”我:“公司创业都十年了……”领导:“这叫沉淀!你们现在的年轻人,真的是,浮躁!”我:“加500行不行。”领导:“最多250。”

我拿着开除证明离开了公司,在写字楼下的停车场,看着领导的大奔,我陷入了沉思……