在工作中,面对这样多种服务,多个服务器,以及多种环境,我们应该如何处理呢?如果还继续用传统的方式打包部署,我们会浪费多少时间?
在Dokcer横空出世之前,应用打包一直是大部分研发团队的痛点,在Docker出现后,它以更高效的利用系统资源、更高效的利用系统资源、一致的运行环境、持续交付和部署、更轻松的迁移、更轻松的维护和拓展,6大优点迅速火了起来。
Docker的基础命令,堪称Docker的内功,只有把内功修炼好了,我们在Docker的学习路上才会更加顺畅,不会导致“走火入魔”。
接下来我将从与虚拟机的对比开始,以实战的方式,带大家更加了解,更会“玩”Docker
名词释义
Server
:物理机服务器
Host OS
:构建的操作系统
Hypervisor
:一种虚拟机软件,装了之后才能虚拟化操作系统
Guest OS
:虚拟化的操作系统
Bins/Libs
:执行命令、工具
App A
:构建的软件
Docker Engine
:跳过虚拟化内核的步骤,直接使用宿主机内核
而对于测试人员,Docker又为我们带来了什么样的便利呢?
在刚开始的时候,由于网络的原因,我们在下载的镜像的时候,常常速度是非常慢的。所以如果下载镜像很慢的同学,可以尝试配置国内的加速器加速镜像下载
vim usr/lib/systemd/system/docker.service
添加红色部分到
"ExecStart" ExecStart=/usr/bin/dockerd --registry-mirror=
保存文件
#重新加载配制:$
systemctl daemon-reload
#重新启动服务:
service docker restart
好记性不如烂键盘,单单只背下来Docker的命令是不够的,还要自己多敲多去练习,才能更熟练、更深刻的掌握Docker。
大家一起勤动小手,通过搭建一个Jenkins环境,去熟悉docker命令哦
(一定要仔细阅读官方镜像的文档)
下载镜像
docker pull jenkins/jenkins
docker images
我们可以看到刚刚下载的Jenkins镜像
那么,其中的每个字段又是什么意思呢?
字段名 | 含义 |
---|---|
REPOSITORY |
REPOSITORY |
TAG |
镜像的版本号,用来指定下载的版本 |
IMAGE ID |
镜像的唯一标识ID |
CREATED |
镜像的制作时间 |
SIZE |
镜像的所占的磁盘空间 |
删除镜像
docker rmi jenkins/IMAGE ID
下载指定版本的镜像
docker pull jenkins:3.1.x
此时我们可以发现,镜像的TAG不再是latest而是我们所指定的版本号
将镜像打包成一个tar包
docker save jenkins:2.60.3 > myjenkins.tar
将打包的镜像加载出来
docker load < myjenkins.tar
给镜像加tag号
docker tag jenkins:latest jenkins:3.6.0
打了tag之后,会发现多了一个3.6.0 tag版本的镜像,但是image ID和原本的保持一致
然后我们删掉这个镜像,发现提示untagged,且这个镜像被成功删除
给镜像改名称
docker tag jenkins:latest testjenkins
然后我们就可以看到,多了一个叫做testjenkins的镜像,但是image ID和原本的保持一致
push镜像到镜像仓库
docker tag jenkins gaofei_com/jenkins
docker push
容器运行命令参数
1. --name 指定容器名称
2. -d 后台运行
3. -port 指定端口映射规则
4. --network 指定容器运行的网路模式
5. -v 指定需要挂载的数据卷
6. -env 指定需要传递给容器的环境变量
容器管理命令参数
1. docker run --name={your_name} --d {image_name} (运行容器)
2. docker ps -s -a {查看当前所有容器}
3. docker stop {container_name} (停止容器)
4. docker kill (container_name) {杀死容器}
5. docker rm -f {container_name/id} (删除容器)
6. docker ps -s (-s表明size)
接下来我们继续使用Jenkins进行一个实战的演练
#启动运行容器
docker run -d --name=myjenkins jenkins/jenkins
#查看当前运行中的容器
docker ps
docker ps
也是我们常用的一个命令,下面是docker ps
后显示的启动容器信息,其中每个字段都有自己的含义
字段名 | 含义 |
---|---|
CONTAINER ID |
容器ID(和image ID无关) |
IMAGE |
启动容器的镜像 |
COMMAND |
容器的启动命令 |
CREATED |
创建时间 |
STATUS |
当前状态 |
PORTS |
容器对外暴露的端口号 |
NAMES |
容器名称 |
CONTAINER ID
:容器ID(和image ID无关)
如何删除这个启动的容器呢?是否可以和镜像一样,直接rm
呢?
docker rm myjenkins
从图中我们可以看到,如果直接删除运行中的容器会报错,需要先stop然后删除
docker stop myjenkins
docker rm myjenkins
或者直接
docker rm -f myjenkins
我们从图片中可以看出,虽然这个容器是启动的状态,但是使用docker rm -f
依然可以直接删除
在docker ps 的时候我们可以看到,PORTS
字段下面显示了两个端口号,这两个端口号是做什么的呢?
其实呀,这两个端口号,是容器故意对外暴露的端口号,我们可以通过端口映射
的方式,使容器内部的端口号与宿主机的某个端口号产生链接。这样我们就可以通过端口号,去访问或者操作容器啦
如何指定端口号呢?就是使用 -p
参数
docker run -d --name=myjenkins -p 8080:8080 jenkins/jenkins
将宿主机的8080端口指向容器的8080端口,这样我们在宿主机的8080端口就可以访问到Jenkins啦
在启动的过程中,我们可能会碰到各种各样的问题,我们如何定位问题呢?
当然是使用查看log大法
docker log -f myjenkins
学到这里,可能有同学会有疑虑啦,如果docker挂掉,在docker内产生的数据应该怎么办呢,这些数据应该如何保存呢
接下来,我们要了解的,docker是如何进行数据持久化的呢?
当我们启动容器时,添加了数据挂载的参数-v 宿主机_path:container_path
,docker就可以通过数据挂载的方式,使容器和宿主机的数据进行同步
保存,
接下来我们通过实战的方式,就可以看到docker是如何实现这一功能的
-v
挂载卷参数docker run --name myjenkins -itd -p 8001:8080 -v /home/gaofei/test/jenkins_home:/var/jenkins_home
注意
:挂载权限:sudo chown -R 1000:1000 /home/docker/jenkins
2. 使用docker exec -it myjenkins bash
进入刚启动的jenkins容器,并cat /var/jenkins_home/secrets/initialAdminPassword
这一步是为了找到jenkins的启动密码
3.输入密码,进入Jenkins页面创建一个job。
4.删掉容器,重新执行之前的命令,重启Jenkins,进入页面,发现job没有因为容器被删而丢失
注意
:如果容器无法成功启动,且log提示权限问题,则在启动命令中添加-u 0
docker exec -it {容器名称} bash
进入容器,exec的意思是在容器中运行一个命令。 如果使用bash 并且指定了-it 就会打开容器的shell 交互
docker exec myjenkins echo "test"
docker exec myjenkins ping www.baidu.com
docker exec -it myjenkins bash
docker cp {container:name}:{container_path} {host_path}
把宿主机上的一个文件copy到容器中
docker cp 1.sh myjenkins:/var/jenkins_home
有一些容器启动时,我们需要给他添加一些初始的参数,比如mysql,我们需要给他添加一些初始的账号和密码,docker如何操作这种情况呢?让我们动动小手,演练一下吧
1.启动mysql容器,注意要加-e
传递参数
docker run --name some-mysql -v /home/gaofei/test/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1qaz9ol. -p 8888:3306 -d mysql:5.5
2.通过数据库连接工具连接数据库
host
要填写宿主机的ip地址,Password
是我们一开始设定的
端口号
填写映射的宿主机的端口号
3. 在数据库中创建一个表
4. 删掉容器,然后重启
5. 进入刚刚创建的容器内的mysql路径下,发现有刚刚添加的表,这个就是容器的数据持久化的功能啦
我们接下来再思考一个问题,因为容器是有隔离性
的
如果容器之间互相链接可以用什么方式?
这里就要引入另外一个参数啦 --link
,这个参数的作用就是把一台容器的网络信息,注入到另外一台容器中
老方法,我们还是通过testlink实战,体验一下这个功能吧
docker run -d --name mariadb -e ALLOW_EMPTY_PASSWORD=yes -e MARIADB_USER=bn_testlink -e MARIADB_DATABASE=bitnami_testlink -v /home/gaofei/test/mysql:/var/lib/mysql -p 8088:3306 bitnami/mariadb:latest
docker run -d --name testlink -p 8099:80 -p 444:443 -e ALLOW_EMPTY_PASSWORD=yes -e TESTLINK_DATABASE_USER=bn_testlink -e TESTLINK_DATABASE_NAME=bitnami_testlink --link mariadb bitnami/testlink:latest
docker logs -f testlink
答案是:--env
因为在docker中,--link
就是通过环境变量的方式配置的。
现在很多网站的架构都是前后端分离,在这种情况下,我们应该如何使用docker分别启动前端和后端,且能互相通信呢?我们可以使用下面的命令
docker run --name=conan -itd -p 8999:4200 conan
docker run --name=holmes -itd --net=container:conan holmes
--net=container:conan
:这样创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
查看docker 的信息
docker info
获取容器/镜像的元数据
docker inspect myjenkins
以上,我们通过实战的方式了解了docker的概念,熟悉了docker的一部分基础命令,看完文章后,就要熟悉练习了哦。下一次,将带大家通过3个实战练习selenium、prometheus+grafana、mysql的监控
,带大家了解docker的招式法门,学会之后,我们就可以真正的带入工作,进行实战了。