Docker的底层原理与简单基础命令

传统虚拟机与docker的区别 

传统虚拟机:完全型解耦
    需要携带操作系统,在系统之上运行应用程序
    调用资源繁琐:
        例如内存调用:利用hypervisor虚拟化内存,整个过程需要 虚拟内存--虚拟物理内存--真正物理内存三步

docker:半解耦
    不携带操作系统,轻巧
    docker引擎分配资源 虚拟内存--真正物理内存

对比        传统虚拟机        docker
磁盘        几个或几十G             几十到几百M
CPU内存        虚拟系统占用过多        docker引擎几乎不占资源
启动速度        几分钟            几秒
安装管理        专门的管理运维        安装管理方便
应用部署        每次部署耗时        第二次开始极其方便
耦合性        多个服务互相干扰        一个服务一个容器,隔离
系统依赖        无            相同相似内核,推荐类Unix


Namespace(名称空间)

名字空间是Linux内核一个强大的特性。每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间彼此互不影响。

**IPC:**                共享内存、消息列队
**MNT:**                 挂载点、文件系统
**NET:**                  网络栈
**PID:**                   进程编号
**USER:**                用户、组
**UTS:**                  主机名、域名

pid 名字空间
不同用户的进程就是通过 pid 名字空间隔离开的,且不同名字空间中可以有相同 pid。所有的 LXC 进程在 Docker 中的父进程为Docker进程,每个 LXC 进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。

net 名字空间
有了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。Docker 默认采用 veth 的方式,将容器中的虚拟网卡同 host 上的一 个Docker 网桥 docker0 连接在一起。

ipc 名字空间
容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication – IPC), 包括信号量、消息队列和共享内存等。然而同 VM 不同的是,容器的进程间交互实际上还是 host 上具有相同 pid 名字空间中的进程间交互,因此需要在 IPC 资源申请时加入名字空间信息,每个 IPC 资源有一个唯一的 32 位 id。

mnt 名字空间
类似 chroot,将一个进程放到一个特定的目录执行。mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个名字空间中的容器在 /proc/mounts 的信息只包含所在名字空间的 mount point。

uts 名字空间
UTS(“UNIX Time-sharing System”) 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。

user 名字空间
每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。

namespace六项隔离,实现了容器与宿主机、容器与容器之间的隔离。



Cgroup(控制组)

控制组(cgroups)是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。

控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。

控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。


mount -t cgroup 

cd /sys/fs/cgroup


四大功能:***

​    1)资源限制:cgroup可以对进程组使用的资源总额进行限制。

​    2) 优先级分配:通过分配的cpu时间片数量以及硬盘IO带宽大小,实际上相当于控制了进程运行的优先级别。

​    3)资源统计:cgroup可以统计系统资源使用量,比如cpu使用时间,内存使用量等,用于按量计费。同时,还支持挂起动能,也就是说通过cgroup把所有资源限制起来,对资源都不能使用,注意着并不是说我们的程序不能使用了,只是不能使用资源,处于等待状态。

​    4)进程控制:可以对进程组执行挂起、恢复等操作。


==============================================
内存限额:

容器内存包括两个部分:物理内存和swap

可以通过参数控制容器内存的使用量:
    -m 或者--memory:  设置内存的使用限额
    --memory-swap: 设置内存+ swap的使用限额

例如:

​运行一个容器,并且限制该容器最多使用200M内存和100M的swap。    
docker run -itd --name container1 -m 200MB --memory-swap 300MB centos:7 


cd /sys/fs/cgroup/memory/docker/545dc2376efedb0d48e174fd8a9a614baf64f99fc09

cat memory.limit_in_bytes 
209715200

cat memory.memsw.limit_in_bytes
314572800

CPU使用

通过-c或者--cpu-shares设置容器使用cpu的权重。如果不设置默认为1024.

例如:

docker run -itd --name container2 -c 512 centos:7 

cd /sys/fs/cgroup/cpu/docker/76178cf366cea1d7a60729f21877d135c25141281ae4b6
cat cpu.shares 
512

对比一个没有做CPU权重限制的容器。

docker run -itd --name container3 centos:7 
cd /sys/fs/cgroup/cpu/docker/4d0858de8e825d362305c05de2293a619d4329ba82dbf8
cat cpu.shares
1024

容器的Block IO

磁盘的读写。

docker中可以通过设置权重,限制bps和iops的方式控制容器读写磁盘的IO.
bps:  每秒读写的数据量      byte per second
iops:  每秒IO的次数         io per second。

默认情况下,所有容器都能够平等的读写磁盘,也可以通过--blkio-weight参数改变容器的blockIO 的优先级。

 --device-read-bps: 显示读取某个设备的bps。
 --device-write-bps: 显示写入某个设备的bps。
 --device-read-iops: 显示读取某个设备的iops。
 --device-write-iops: 显示写入某个设备的iops。

例如:限制testA这个容器,写入/dev/sda这块磁盘的bps为30MB.

docker run -it  --name testA --device-write-bps /dev/sda:30MB centos:7

从/dev/zero输入,然后输出到test.out文件中,每次大小为1M,总共800次,oflag=direct 用来指定directIO方式写文件,这样才会使--device-write-bps生效。

time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 26.6228 s, 31.5 MB/s

real    0m26.629s
user    0m0.005s
sys    0m1.902s


再运行一个不做限制testB容器,对比一下速率
docker run -itd --name testb centos:7 
docker exec -it testb /bin/bash
time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 2.32559 s, 361 MB/s

real    0m2.328s
user    0m0.000s
sys    0m2.107s


====================================
查看镜像
docker images

查看所有容器
docker ps -a

查看运行的容器
docker ps 

保存镜像
docker save -o nginx.tar nginx:latest

载入镜像
docker load -i nginx.tar

停止容器
docker stop 容器名或id号 

删除容器
docker rm 容器名或id号

删除镜像
docker rmi nginx:latest

进入容器
docker exec -it testA /bin/bash

Docker的常用命令

1、帮助命令

docker version         #显示docker的版本信息。
docker info         #显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help     #帮助命令
帮助文档的地址:https://docs.docker.com/engine/reference/commandline/docker/

2、镜像命令

docker images         #查看所有本地主机上的镜像 可以使用docker image ls代替
docker search         #搜索镜像
docker pull         #下载镜像 docker image pull
docker rmi             #删除镜像 docker image rm

docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   4 months ago   13.3kB
# 解释
REPOSITORY   镜像的仓库源
TAG          镜像的标签
IMAGE ID     镜像的ID
CREATED      镜像的创建时间
SIZE         镜像的大小
# 可选项
  -a, --all             # 列出所有的镜像
  -q, --quiet           # 只显示镜像的id

docker images -aq     #显示所有镜像的id


docker search 搜索镜像

docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   11138     [OK]       
mariadb                           MariaDB Server is a high performing open sou…   4221      [OK]       
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   829       [OK]
percona                           Percona Server is a fork of the MySQL relati…   547       [OK]       
phpmyadmin                        phpMyAdmin - A web interface for MySQL and M…   274       [OK]       
centos/mysql-57-centos7           MySQL 5.7 SQL database server                    89                   
mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   88   

# 可选项
--filter=STARS=3000   # 搜索出来的镜像就死starts 大于3000的

docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   11138     [OK]       
mariadb   MariaDB Server is a high performing open sou…   4221      [OK]


docker pull 下载镜像

# 下载镜像 docker pull 镜像名[:tag]
docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
b4d181a07f80: Pull complete 
a462b60610f5: Pull complete 
578fafb77ab8: Pull complete 
524046006037: Pull complete 
d0cbe54c8855: Pull complete 
aa18e05cc46d: Pull complete 
32ca814c833f: Pull complete 
9ecc8abdb7f5: Pull complete 
ad042b682e0f: Pull complete 
71d327c6bb78: Pull complete 
165d1d10a3fa: Pull complete 
2f40c47d0626: Pull complete 
Digest: sha256:52b8406e4c32b8cf0557f1b74517e14c5393aff5cf0384eff62d9e81f4985d4b
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
# 等价于
docker pull mysql
docker pull docker.io/library/mysql:latest

# 指定版本下载
docker pull mysql:5.7
5.7: Pulling from library/mysql
b4d181a07f80: Already exists 
a462b60610f5: Already exists 
578fafb77ab8: Already exists 
524046006037: Already exists 
d0cbe54c8855: Already exists 
aa18e05cc46d: Already exists 
32ca814c833f: Already exists 
52645b4af634: Pull complete 
bca6a5b14385: Pull complete 
309f36297c75: Pull complete 
7d75cacde0f8: Pull complete 
Digest: sha256:1a2f9cd257e75cc80e9118b303d1648366bc2049101449bf2c8d82b022ea86b7
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7


docker rmi 删除镜像

docker rmi -f 镜像id                     # 删除指定的镜像
docker rmi -f 镜像id 镜像id 镜像id 镜像id       # 删除多个镜像
docker rmi -f $(docker images -aq)             # 删除全部的镜像


3、容器命令

docker run 镜像id         #新建容器并启动
docker ps                 #列出所有运行的容器 docker container list
docker rm 容器id         #删除指定容器
docker start 容器id     #启动容器
docker restart容器id     #重启容器
docker stop 容器id         #停止当前正在运行的容器
docker kill 容器id         #强制停止当前容器
docker pause 容器id     #挂起容器
docker unpause 容器id         #恢复挂起
docker commit 容器id 镜像名     #把容器制作成镜像

说明:有镜像才可以创建容器,linux,下载一个centos镜像来测试学习
docker pull centos:7

新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name"     容器名字   tomcat01   tomcat02,  用来区分容器
-d                后台方式运行
-it               使用交互方式运行,进入容器查看内容
-p                指定容器的端口 -p  8080:8080
    -p   ip:主机端口:容器端口
    -p   主机端口:容器端口(常用)
    -p   容器端口(随机映射到外部端口,一般32000+)

-P       随机映射端口

案例:
docker run -d --name web1 -p 8080:80 nginx    #指定端口映射
docker run -d --name web2 -p 8081:80 nginx    
docker run -d --name web3 -p 80 nginx        #随机映射端口
docker run -d --name web4 -P nginx            #随机映射端口


# 测试,启动并进入容器
docker run -it centos:7 /bin/bash
[root@90262d2cbb32 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 从容器中退回主机,容器关闭(想要容器持续运行,添加参数-d)
[root@90262d2cbb32 /]# exit
exit


列出所有的运行的容器

#docker ps命令 #列出当前正在运行的容器
    # 列出当前正在运行的容器
-a  # 列出当前正在运行的容器+带出历史运行过的容器
-q  # 只显示容器的编号

docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
a199a44bb07c   centos    "/bin/bash"   23 minutes ago   Up 23 minutes             compassionate_feynman

docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS                     PORTS     NAMES
90262d2cbb32   centos         "/bin/bash"   4 minutes ago    Exited (0) 3 minutes ago             zen_cerf
a199a44bb07c   centos         "/bin/bash"   23 minutes ago   Up 23 minutes                        compassionate_feynman
2a70eb3c087c   d1165f221234   "/hello"      25 hours ago     Exited (0) 25 hours ago              bold_darwin

退出容器
exit    

删除容器
docker rm 容器id                 # 删除指定容器,不能删除正在运行的容器,如果要强制删除  
docker rm -f $(docker ps -aq)     # 删除所有的容器
docker ps -a -q | xargs docker rm -f      # 删除所有的容器

启动和停止容器的操作
docker start 容器id     #启动容器
docker restart 容器id  #重启容器
docker stop 容器id      #停止当前正在运行的容器
docker kill 容器id      #强制停止当前容器

4、常用其他命令

后台启动容器
# 命令 docker  run -d 镜像名!

docker run -d centos:7 
# 问题docker  ps,发现centos停止了
# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程, docker 发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

查看日志
docker logs --help
Usage:  docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:      
    --details                显示更多的信息  
    -f, --follow             跟踪日志输出,最后一行为当前时间戳的日志      
    --since string           显示具体某个时间或时间段的日志
    -n, --tail string        从末尾显示多少行,默认all 
    -t, --timestamps         显示时间戳      
    

#命令测试看日志
docker logs -f -t --details  容器id

# 自己编写一段shell脚本
docker run -d centos:7 /bin/sh -c "while true;do echo 6666;sleep 1;done" #模拟日志

docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES596b80f933ac   centos    "/bin/sh -c 'while t…"   9 seconds ago   Up 8 seconds             priceless_meninsky

# 显示日志
-tf                #显示日志
--tail=number         #要显示日志条数
docker logs -tf --tail 10 596b80f933ac
docker logs -tf --tail=10 596b80f933ac


查看容器中进程信息 ps

# 命令 docker top 容器id
docker top 596b80f933ac
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                10528               10491               0                   17:17               ?                   00:00:00            /bin/sh -c while true;do echo 6666;sleep 1;done
root                11362               10528               0                   17:23               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1


查看镜像的元数据

# 命令
docker inspect 容器id
#测试
docker inspect 596b80f933ac


进入当前正在运行的容器  *****

# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id bashShell   

# 测试
docker exec -it 596b80f933ac /bin/bash
ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jul19 ?        00:00:17 /bin/sh -c while true;do echo 6666;sleep 1;done
root     23455     0  0 00:51 pts/0    00:00:00 /bin/bash
root     23704     1  0 00:55 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root     23705 23455  0 00:55 pts/0    00:00:00 ps -ef

# 方式二
docker attach 容器id
# 测试
docker attach 596b80f933ac
正在执行当前的代码。。。。
# docker exec    #进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach  #进入容器正在执行的终端,不会启动新的进程!

从容器内拷贝到主机上
docker cp 容器id:容器内路径   目的的主机路径

docker attach 0b308ba7528d
cd /home
ls
# 在容器内新建一个文件
touch test.java
exit
# 将这个文件拷贝出来到主机上
docker cp 0b308ba7528d:/home/test.java /home

# 拷贝是一个手动过程,使用 -v 卷的技术,可以更容易实现

==============================
总结:
attach    Attach to a running container                                  #当前shell下attach连接指定运行镜像
build     Build an image from a Dockerfile                               #通过Dockerfile定制镜像
commit    Create a new image from a containers changes                   #提交当前容器为新的镜像
cp          Copy files/folders from a container to a HOSTDIR or to STDOUT  #从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container                                         #创建一个新的容器,同run 但不启动容器
diff      Inspect changes on a containers filesystem                     #查看docker容器变化
events    Get real time events from the server                           #从docker服务获取容器实时事件
exec      Run a command in a running container                           #在已存在的容器上运行命令
export    Export a containers filesystem as a tar archive                #导出容器的内容流作为一个tar归档文件(对应import)
history   Show the history of an image                                   #展示一个镜像形成历史
images    List images                                                    #列出系统当前镜像
import    Import the contents from a tarball to create a filesystem image  #从tar包中的内容创建一个新的文件系统映像(对应export)
info      Display system-wide information                                #显示系统相关信息
inspect   Return low-level information on a container or image           #查看容器详细信息
kill      Kill a running container                                       #kill指定docker容器
load      Load an image from a tar archive or STDIN                      #从一个tar包中加载一个镜像(对应save)
login     Register or log in to a Docker registry                        #注册或者登陆一个docker源服务器
logout    Log out from a Docker registry                                 #从当前Docker registry退出
logs      Fetch the logs of a container                                  #输出当前容器日志信息
pause     Pause all processes within a container                         #暂停容器
port      List port mappings or a specific mapping for the CONTAINER     #查看映射端口对应的容器内部源端口
ps        List containers                                                #列出容器列表
pull      Pull an image or a repository from a registry                  #从docker镜像源服务器拉取指定镜像或者库镜像
push      Push an image or a repository to a registry                    #推送指定镜像或者库镜像至docker源服务器
rename    Rename a container                                             #重命名容器
restart   Restart a running container                                    #重启运行的容器
rm        Remove one or more containers                                  #移除一个或者多个容器
rmi       Remove one or more images                                      #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run       Run a command in a new container                               #创建一个新的容器并运行一个命令
save      Save an image(s) to a tar archive                              #保存一个镜像为一个tar包(对应load)
search    Search the Docker Hub for images                               #在docker hub中搜索镜像
start     Start one or more stopped containers                           #启动容器
stats     Display a live stream of container(s) resource usage statistics  #统计容器使用资源
stop      Stop a running container                                       #停止容器
tag       Tag an image into a repository                                 #给源中镜像打标签
top       Display the running processes of a container                   #查看容器中运行的进程信息
unpause   Unpause all processes within a container                       #取消暂停容器
version   Show the Docker version information                            #查看容器版本号
wait      Block until a container stops, then print its exit code        #截取容器停止时的退出状态值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值