docker

一直都听老师和同学们在说docker好啊,之前也用过,但是又忘了,现在进行一些总结。

参考博客

博客园
如何通俗解释Docker是什么?
Docker 入门教程

介绍

“Docker是一个开源的应用容器引擎,Docker能够让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,方便快捷。”这是CSDN说的云计算时代,你真的懂Docker吗?
每一次都感觉最难的往往是在理解这个概念上
我们去知乎看看
如何通俗解释Docker是什么?

直观理解V1.0

参照知乎高赞回答——刘允鹏的回答
回答者是根据docker的图标来着,docker的图标是一个鲸鱼托着集装箱
我们想象现在的那些大轮船,上面的货物都被分类用集装箱装起来了,因为集装箱的存在,所以船上装的东西可以是各式各样的。
而docker就相比于这个鲸鱼,而container才是集装箱(原文作者说的有点儿问题)
考虑两个场景:
不同的应用程序可能需要不同的运行环境,有可能会造成冲突,这个时候我们肯定不能让它们在同一台机子上跑了,这个时候可以将它们部署到不同的虚拟机上,但是虚拟机开销大,而docker又可以实现隔离应用环境的功能,所以此时可以开docker;
比如开发者写的一个程序可能到另外一个人的系统上可能不能正常运行,因为环境的差异可能导致这类问题较多,如果重新配置环境会花费较长的时间,所以此时可以使用docker
可是看完了感觉还不是很清晰

理解V1.1

看了好多回答,感觉有一些理解,下面总结一下
先看看docker和常用的虚拟机之间的架构区别:
1
可以看到虚拟机是通过hypervisor来进行硬件层模拟和虚拟化,然后在其上再跑各自的系统,而docker中的各容器是共用一套内核/系统的,类比于合租
Docker本身并不是容器,它是创建容器的工具,是容器引擎,容器在docker上运行
Docker中有几个概念:

  1. 镜像Image,相当于一个软件包,里面打包了应用程序和它运行时的执行环境(比如说依赖),然后该镜像就可以分发给别人
  2. 容器Container,就是用镜像创建的运行实例,一个很好的类比是,镜像是类,而容器就是类实例化的对象,同一个 image 文件,可以生成多个同时运行的容器实例
  3. 仓库Repository,存储各镜像的地方

也就是说镜像相当于别人弄好的模板,然后到你这,你跑起来就成了容器
由此看来,Docker相当于一个管理机构,可创建容器、可销毁容器等
Docker可以使其上运行的容器简单隔,采用的是linux的cgroup机制实现的资源隔离(啥时候看看再详细学一下cgroup技术)
Docker采用的是C/S架构,可从S端pull人家上传的镜像,如下图所示:
2
最左边是docker客户端,是用户与docker服务交互的窗口
中间的是docker后台运行的服务,docker daemon是一个进程,docker deamon监听着客户端的请求,并且管理着docker的镜像、容器、网络、磁盘(图中只列出了镜像与容器)等对象。同样,docker的客户端与服务可以运行在同一机器上,也可以用某台机器上的客户端远程连接另一台机器上的docker服务。
右边是镜像仓库

由此再给docker下个定义:docker是以容器技术为核心的一套应用的构建、分发和执行的体系和生态。
看了腾讯的一节课,上面的老师分享的经验是:

  1. 一个容器只运行一个应用
  2. 分层构建镜像,任何镜像的创建会基于其他的父镜像,也就是说镜像是一层套一层,比如一个tomcat镜像,需要运行在centos/ubuntu上,那我们的tomcat镜像就会基于centos/ubuntu镜像创建
  3. 善于使用dockerfile来生成镜像,而不是用docker commit
  4. 不要把它当成虚拟机来用

感觉差不多知道是个啥了,下面我们来实际操作一下docker

安装docker

我们来安装一下docker
我的实验环境是在ubuntu16.04虚拟机上
Windows上也可以使用docker,但是需要先开启Hyper-V,这个目的就是虚拟出一个Linux来,然后在其上运行docker
参考博客docker安装还可以参考官方文档啊,这篇文档其实就是从官方那翻译来的

  1. 由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本
    $ sudo apt-get remove docker docker-engine docker-ce docker.io
  2. 更新apt包索引
    $ sudo apt-get update
  3. 安装以下包以使apt可以通过HTTPS使用存储库(repository)
    $ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    (apt-get install -y如果有yes/no,默认yes)
  4. 添加Docker官方的GPG密钥
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  5. 为了验证你有这个9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88指纹,可以查看指纹的最后8个字符
    $ sudo apt-key fingerprint 0EBFCD88
  6. 使用下面的命令来设置stable存储库
    $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  7. 再更新一下apt包索引
    $ sudo apt-get update
  8. 安装最新版本的Docker CE
    $ sudo apt-get install docker-ce docker-ce-cli containerd.io
  9. 查看docker服务是否启动
    $ systemctl status docker
  10. 若未启动,则启动docker服务
    $ sudo systemctl start docker
  11. 验证
    $ sudo docker run hello-world
    出现下图代表安装成功了
    3

还可以使用镜像加速

参考博客Docker镜像加速

用docker开一个mysql服务

参考博客Docker上运行MySQL服务通过这个例子,我们来学习一下docker的简单使用
sudo docker images,可以看到此时有一个hello-world的镜像
sudo docker container ls可以看到此时的container是空的
搜索MySQL镜像sudo docker search mysql
我们选第一个星最多且是官方的
sudo docker pull mysql
发现此时命令中说的是Using default tag:latest,也就是下的是最新版本
要想指定版本呢?
可以去docker的镜像仓库里找,可视化界面
docker仓库
然后sudo docker pull mysql:1.1这条命令是假设的啊
不行太慢了,转回去使用加速
速度果然飞快
sudo dcoker images发现此时有了mysql的镜像
下面就要运行该镜像创建容器了
docker run -d --name test-mysql -e MYSQL_ROOT_PASSWORD=password mysql
docker run有很多参数,可以自行百度,这里的-d指的是后台运行容器并返回容器id
–name就是为容器指定一个名字;-e设置环境变量,这里设置的是root的密码为password,最后面跟的就是镜像
但是如果简单的使用上述命令创建容器的话,会导致容器删除后数据丢失,并且此时外界连不上该数据库,只能到容器内部使用,所以需要改进
具体过程如下:

  1. 创建宿主机数据存放目录mkdir -p /opt/data/mysql
  2. 查看本机3306端口是否被进程占用lsof -i:3306
  3. 创建容器docker run -d -v /opt/data/mysql/:/var/lib/mysql -p 3306:3306 --name test-mysql -e MYSQL_ROOT_PASSWORD=password mysql

-v /opt/data/mysql:/var/lib/mysql->把宿主机/opt/data/mysql/目录映射到容器的/var/lib/mysql目录
-p 3306:3306->把容器的mysql端口3306映射到宿主机的3306端口,这样想访问mysql就可以直接访问宿主机的3306端口,如果3306被占用了可以使用别的端口
4. 用位于虚拟机外的navicat链接发现报2059错误,上网上找了一篇解决方案
解决方案
这是由于新版本的MySQL使用的是caching_sha2_password验证方式,但此时的navicat还没有支持这种验证方式。
5. 进入容器docker exec -it test-mysql /bin/bash也可以使用run命令,不过run命令一般用在创建的时候,然后以命令行交互;exec是在运行的容器中执行命令
这里有一个问题需要注意“这里-t给容器绑上了一个伪终端并绑定到容器的标准输入上, -i则让容器的标准输入保持打开”,还可以docker exec test-mysql ls,/bin/bash是打开容器内的一个终端近程,又因为it的等待 所以就会一直以终端连接的方式停留在容器内部
6. 进入数据库mysql -u root -p;选择数据库use mysql;;查看用户加密规则select user,plugin from user where user='root';;更改加密方式alter user 'root'@'%' identified by 'password' password expire never;alter user 'root'@'%' identified with mysql_native_password by 'password';;再次查看用户加密规则select user,plugin from user where user='root';;刷新权限flush privileges;
注意远程连接为‘root’@’%’,本地连接为‘root’@’localhost’

然后navicat可以连接使用了
退出容器输入exit
查看容器日志可输入docker logs test-mysql
停止容器docker stop test-mysql;启动被停止的容器docker start tets-mysql;重启是restart
docker ps列出正在运行的容器,-a :显示所有的容器,包括未运行的。
docker create :创建一个新的容器但不启动它,用法同run
docker rm 容器iddocker rmi 镜像id -f 强制删除
我先把test-mysql暂停了,后续再用
好了,关于docker的简单使用先介绍这些,像dockerfile(制作镜像地就没有用过),如果啥时候又用了,或者又有新的理解了,再补充吧。