本小节总结以下的几点
- 容器技术和Docker的简介
- Docker的安装
- Docker的常用命令
一、容器技术和Docker的简介
-
问题:为什么会出现容器技术呢?
很久以前,我们要在一台物理设备上进行部署,那么我们就需要在上面装上操作系统win或者linux,然后在操作系统上面装我们所要用的application。
这种模式的缺点:
1、部署慢,需要服务器,需要按系统,需要安装app
2、成本很高,需要物理的服务器
3、资源的浪费,服务器资源太多了 ,内存和CPU用不完
4、难以迁移和扩展。扩展是说app消耗很大,本台服务器的资源不够了,这个时候就需要扩展来满足需求。
5、可能被限定的厂商给限定死了。 -
针对以上的缺点,就出现我们熟悉的虚拟机。
虚拟技术就是在以前的服务器上加上了一层Hypervisor,去做物理资源的调度,比如CPU、内存等资源,然后再在这个Hypervisor上,去装虚拟机VM。我们底层的物理服务器的资源还是挺多的。这样我们就能实现虚拟机之间资源的一个调度,比如VM1上面1个CPU和8G内存,然后VM2上面是2个CPU和12G内存,这样的话我们就做出了限定。
VM的优点
1、资源池
2、很容易扩展,加虚拟机,我们可以加第四台。要是物理机资源不够,还可以加物理机。Hypervisor做了一层
3、很容易云化,AWS和阿里云、腾讯云,可以通过公有云创建虚拟机,不用知道物理机放在那里,现在的公司都采用了虚拟化技术了
虚拟化的局限性: 每个VM都是一个完整的OS,那么它需要给其分配资源,还没有部署app的时候,OS就占了很多资源了。当VM的数量很多的时候,OS本身消耗的资源势必增多。但是这不是容器出现最主要的原因。
虚拟机与容器的对比 -
容器出现的最主要的原因
开发和运维之间会出现扯皮的情况,开发在本机上面是好的。交付上面,开发与运维之间有问题。为什么开发这里好,但是在运维上面出问题呢?问题出现的原因是环境与配置,比如你本地在windows上面进行了开发,然后运维是要将这个部署到阿里云上面,这个时候环境就变了。一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。
虚拟机与容器的对比总结如下所示:
1 | 2 | 3 |
---|---|---|
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活、适应于LInux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
二、Docker的安装
2.1、docker的基本组成和架构
安装之前,我们来先看看docker的三大核心部分,如下:
Docker的三大核心
Docker的基本组成是由镜像(image)、容器(container)和仓库(repository)组成。
- 镜像:就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
- 容器:Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
- 仓库:仓库(Repository)是集中存放镜像文件的场所。仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。目前最大的仓库就是docker hub。国内的阿里云和网易云对docker hub上面的镜像进行了一个备份的操作。国内的话,还是将仓库设置成阿里云的,这样的话,能够快速的将我们想要的镜像给拉下来。
然后我们在看看docker的架构图,如下:
容器架构图在这里,Client就是我们的docker的客户端,然后Host就是我们的系统,可以看出我们的系统里面有多个镜像,镜像的实例就是我们的容器。我们的host可以从远端的仓库拉镜像下来。
2.2、Docker的安装
Docker的安装来说就显得挺简单了。跟着官网来就行了,这里给大家几个链接去安装就行了
-
Mac安装
去docs.docker.com/install/下载
直接安装就好了
- centos
1、确定centos的版本
2、到官网根据https://docs.docker.com/install/linux/docker-ce/centos/上面的步骤进行一步一步安装就好了
2.3、容器的运行
三、Docker的常用命令
下面的思维导图简要的总结了一下我们常用的docker命令:
Docker常用命令思维导图
3.1、帮助命令
帮助命令主要有三个:docker version、docker info、docker --help
要是有些命令记不住了,可以直接docker --help一下,看看各个命令的意义。这里就不记这三个命令的使用了。
3.2、镜像命令
(1)docker images
☁ ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE`
由于我的电脑上面没有任何的镜像的存在,所以就是空的。下面我们拉一个hello-world下来看看:
☁ ~ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest
拉取完了hello-world之后,我们再采用docker images看看
☁ ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 2 months ago 1.84kB
这里的标签说明:
REPOSITORY :镜像的仓库源
TAG:镜像的标签,latest表示是最新的版本。
IMAGE ID :镜像的ID
CREATED:镜像的创建时间
SIZE:镜像的大小
同一个仓库源可以有很多个TAG,代表它有很多个不同的版本。采用REPOSITORY: TAG的形式来定义不同的镜像。如果看不到镜像名后面的标签,那么就是默认为镜像名:latest
前面的思维导图里面已经看到了-a、-q、--no-trunc的作用:
☁ ~ docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 2 months ago 1.84kB
☁ ~ docker images -q
fce289e99eb9
☁ ~ docker images -aq
fce289e99eb9
☁ ~ docker images --no-trunc
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e 2 months ago 1.84kB
这里我们可以结合a和q,拿到所有镜像的id,然后实现一个删除的操作。
(2)docker search
docker search 镜像名 ---> 可以去docker hub上面寻找镜像,我们可以看到搜索centos的话,就有很多的镜像了,有描述、点赞数、是不是官方的。
☁ ~ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 5227 [OK]
ansible/centos7-ansible Ansible on Centos7 120 [OK]
jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86… 107 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 81 [OK]
imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 50 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 47
tutum/centos Simple CentOS docker image with SSH access 43
gluster/gluster-centos Official GlusterFS Image [ CentOS-7 + Glust… 40 [OK]
openshift/base-centos7 A Centos7 derived base image for Source-To-I… 39
centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 37
centos/python-35-centos7 Platform for building and running Python 3.5… 33
kinogmt/centos-ssh CentOS with SSH 26 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 21
openshift/jenkins-2-centos7 A Centos7 based Jenkins v2.x image for use w… 20
centos/php-56-centos7 Platform for building and running PHP 5.6 ap… 19
pivotaldata/centos-gpdb-dev CentOS image for GPDB development. Tag names… 10
openshift/wildfly-101-centos7 A Centos7 based WildFly v10.1 image for use … 6
openshift/jenkins-1-centos7 DEPRECATED: A Centos7 based Jenkins v1.x ima… 4
darksheer/centos Base Centos Image -- Updated hourly 3 [OK]
pivotaldata/centos-mingw Using the mingw toolchain to cross-compile t… 2
pivotaldata/centos Base centos, freshened up a little with a Do… 2
pivotaldata/centos-gcc-toolchain CentOS with a toolchain, but unaffiliated wi… 1
blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK]
openshift/wildfly-81-centos7 A Centos7 based WildFly v8.1 image for use w… 1
smartentry/centos centos with smartentry 0 [OK]
有的时候,docker search的个数太多,所以我们可以选择过滤一下,也就是思维导图里面的加上-s来列出收藏数不小于指定值的镜像
☁ ~ docker search -s 100 centos
Flag --stars has been deprecated, use --filter=stars=3 instead
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 5227 [OK]
ansible/centos7-ansible Ansible on Centos7 120 [OK]
jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86… 107 [OK]
(3)docker pull
docker pull centos等价于docker pull centos:latest,默认拉取的就是centos最新版本的镜像。
☁ ~ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a02a4930cb5d: Pull complete
Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Status: Downloaded newer image for centos:latest
(4)docker rmi
因为是删除镜像,所以是接rmi。这里需要注意的是要是镜像的一个容器正在使用中的话,采用docker rmi 镜像名来删除的话,是行不通的。需要采用docker rmi -f 镜像名的方式来强制删除这个镜像。
### 这个之前运行了docker run hello-world这个命令
☁ ~ docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container b2b8498f9086 is using its referenced image fce289e99eb9
在上面的命令基础上面加上f之后,就顺利删除掉了
☁ ~ docker rmi -f hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
删除之后就不见hell-world镜像了。
☁ ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest dd6ff929584a 12 hours ago 463MB
centos latest 1e1148e4cc2c 3 months ago 202MB
然后我们来删除全部的images,:docker rmi -f $(docker images -aq),这里就利用到了我们前面的aq命令了。
☁ ~ docker rmi -f $(docker images -aq)
3.3、容器命令
Docker利用容器独立运行一个多着多个应用,容器就是镜像创建的一个实例了。它可以被启动、开始、停止和删除。而且每一个容器都是相互隔离开来的,保证安全你的平台。
(1)新建并启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
参数options:
--name="容器新名字": 为容器指定一个名称;
-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-P: 随机端口映射;
-p: 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
使用镜像centos:latest以交互模式启动一个容器。这样操作就进入了容器centos了,然后我们可以看见我们处在了当前的根目录下面。
☁ ~ docker run -it centos
[root@a5874f60f4a8 /]# pwd
/
[root@a5874f60f4a8 /]#
然后我们可以看看docker容器里面的状态,
[root@35cd9cdd095b /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:43 pts/0 00:00:00 /bin/bash
root 16 1 0 08:43 pts/0 00:00:00 ps -ef
(2) docker ps [options]
列出我们当前正在运行的容器的命令。
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
--no-trunc :不截断输出。
直接用docker ps就能看到当前正在运行的容器
☁ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a5874f60f4a8 centos "/bin/bash" 3 minutes ago Up 3 minutes dreamy_goldberg
☁ ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35cd9cdd095b centos "/bin/bash" 3 minutes ago Up 3 minutes clever_mclean
30d1fa5ccf3a hello-world "/hello" 17 minutes ago Exited (0) 17 minutes ago inspiring_chandrasekhar
☁ ~ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35cd9cdd095b centos "/bin/bash" 3 minutes ago Up 3 minutes clever_mclean
☁ ~ docker ps -q
35cd9cdd095b
☁ ~ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35cd9cdd095bc42175c3b9977e95810d8a9edbfd4e4954cd56d05122ab5b610a centos "/bin/bash" 4 minutes ago Up 4 minutes clever_mclean
(3)容器退出的两种方式
1、exit:容器停止并退出,这样去docker ps查看的时候,就没有当前运行的容器信息。
2、ctrl+P+Q:就是保持容器不停止,但是我们也退出了。
(4)容器的启动、重启、停止、强制停止以及删除容器
启动: docker start 容器ID或者容器名
~ docker start 35cd9cdd095b
35cd9cdd095b
☁ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
35cd9cdd095b centos "/bin/bash" 15 minutes ago Up 10 seconds clever_mclean
停止:docker stop 容器ID或者容器名
☁ ~ docker stop 35cd9cdd095b
35cd9cdd095b
☁ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
注意一下这里stop是温柔的停止,然后kill是暴力的停止。
我们已经有很多个容器了,那么我们也可以对容器进行一个删除的操作
删除容器:docker rm 容器ID或者容器名。
一次性删除多个容器:docker rm -f $(docker ps -aq)或者 docker ps -aq | xargs docker rm
☁ ~ docker rm -f $(docker ps -aq)
35cd9cdd095b
30d1fa5ccf3a
(5)重要的一些命令
- 启动守护式容器
☁ ~ docker run -d centos
abab374ce58fd473044ad0bbca4a39d21cea323fd32cd2844364a6a09b72812b
☁ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
在这里,我们看到了我们采用了启动守护式容器的方式进行运行了之后,但是docker ps并没有发现运行了。为什么会这样呢?
因为Docker容器后台运行,就必须有一个前台进程.容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如service nginx start。但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
- 查看容器日志
docker run -d centos /bin/sh -c 'while true;do echo hello bear;sleep 2;done'
☁ ~ docker run -d centos /bin/sh -c 'while true;do echo hello bear;sleep 2;done'
0bdad01a4f53f860615932d1ecf57672f4ed4a5e6f9ef569b6adb4b476f719fa
☁ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0bdad01a4f53 centos "/bin/sh -c 'while t…" 11 seconds ago Up 10 seconds hardcore_jennings
docker logs + 容器id ---->查看日志
☁ ~ docker logs 0bdad01a4f53
hello bear
hello bear
hello bear
hello bear
hello bear
hello bear
hello bear
hello bear
hello bear
docker logs -t + 容器id ---->查看日志,加上了时间戳
☁ ~ docker logs -t 0bdad01a4f53
2019-03-06T01:50:28.701813500Z hello bear
2019-03-06T01:50:30.711125000Z hello bear
2019-03-06T01:50:32.715700300Z hello bear
2019-03-06T01:50:34.716762300Z hello bear
2019-03-06T01:50:36.720626500Z hello bear
2019-03-06T01:50:38.723566900Z hello bear
2019-03-06T01:50:40.691119800Z hello bear
2019-03-06T01:50:42.693349700Z hello bear
2019-03-06T01:50:44.695585100Z hello bear
2019-03-06T01:50:46.698940300Z hello bear
2019-03-06T01:50:48.701926000Z hello bear
-t -f 就是不停的追加,因为是每两秒钟打印一下。因为太多了,看着有点蛋疼,所以我们就需要看后面的三行了,这里就用到了--tail+我们要看的行数了
☁ ~ docker logs -t -f --tail 3 0bdad01a4f53
2019-03-06T01:53:38.848574200Z hello bear
2019-03-06T01:53:40.855578300Z hello bear
2019-03-06T01:53:42.857704300Z hello bear
2019-03-06T01:53:44.861998600Z hello bear
2019-03-06T01:53:46.866374400Z hello bear
2019-03-06T01:53:48.871097600Z hello bear
2019-03-06T01:53:50.875416000Z hello bear
2019-03-06T01:53:52.877975100Z hello bear
感觉这个和linux里面的命令差不多
- 查看容器内运行的进程
docker top 容器ID
☁ ~ docker top b9d40b1f1c37
PID USER TIME COMMAND
3160 root 0:00 /bin/sh -c while true;do echo hello bear;sleep 2;done
3328 root 0:00 sleep 2
- 查看容器内部的细节
docker inspect + 容器ID 按照一个json串的形式返回。返回了一个很长的json了。Inspect一个json的串的形式。看到具体的细节 - 进行入正在运行的容器并以命令行交互
~ docker run -it centos
[root@583aeaf26957 /]# % ☁ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
583aeaf26957 centos "/bin/bash" 22 seconds ago Up 21 seconds heuristic_banzai
进入到容器中:docker attach 容器ID
☁ ~ docker attach 583aeaf26957
[root@583aeaf26957 /]#
Exec是另外一种方式了。意思就是进入到容器,然后执行后面的一个命令,这个好处就是不用交互式的进去。
☁ ~ docker exec -t 583aeaf26957 ls -l /tmp
total 4
-rwx------ 1 root root 836 Mar 5 17:36 ks-script-eC059Y
-rw------- 1 root root 0 Mar 5 17:34 yum.log
-
从容器拷贝文件到主机上
docker cp 容器ID:容器内路径 目的主机路径
命令和Linux里面的拷贝差不多
Docker Commands Diagram
总结,这一部分就简单的介绍了一下Docker、Docker的安装和Docker的常用命令,喜欢的小伙伴,就点个赞哈。
持续更新中...
参考资料:
1、https://www.docker.com/
2、https://www.bilibili.com/video/av17854410?from=search&seid=2496603295204351706
网友评论