一、初识Docker
Docker是什么?
Docker的本质其实就是一个软件,管理了他所创建的进程,所谓的容器,其实就是这个进程。就像MySQL一样,其实也是一个软件,管理他创建的数据库,也就是管理一个数据容器。所以说Docker和虚拟机不一样,并没有去虚拟什么硬件设备之类的,也不会把所有的程序都跑在一个Docker容器中,而是遵循单一原则,一个程序只运行在一个容器中。而他管理自己创建的进程的方法,也是参考了linux隔离进程的逻辑,并没有自己实现一套隔离机制,而是直接采用了进程的隔离机制。
Docker解决了什么问题?怎么解决的?
1、通过封装进程以及他的运行环境,解决了应用程序在 本地运行环境和在生产运行环境的 环境不一致问题。
2、通过为每个程序指定内存分配和CPU分配,解决了应用程序资源使用的问题
二、Docker的容器隔离
1、RootFs
是Docker容器的根目录,就像Linux中的每个进程,都也有一个自己的根文件系统(根目录),也就相当于实现隔离的"地板",隔离文件系统,容器有自己的根文件,提供了容器运行的所有依赖。
RootFs的构成是镜像层(只读)+容器层(可写),对容器而言就是一个完整的根文件系统,每个容器都有一个RootFs,所以为了节省存储空间,镜像层是会被多个容器共享的,启动一个容器的时候也无需复制镜像,只需要创建新的容器层,来承载容器对文件的修改。
2、Namespace
每个容器也都有自己的Namespace实例,相当于实现隔离的"周围四面墙",让每个容器误以为自己拥有独立的进程树、网络栈(IP、端口、路由表)、挂载点、IPC进程间通信、用户/组 ID。
3、控制组cgroup
cgroup来控制容器(多个进程(一主多从))能够使用的资源,比如内存、cpu等,相当于实现隔离的"天花板"。
实操命令
限制内存 512M : docker run -m 512m MyNginx
限制CPU使用率 50% : docker run --cpus 0.5 MyNginx
三、Docker的缺点
1、对于IO 密集型应用,性能损耗不可接受。比如Mysql,对磁盘 IO、网络 IO、CPU 都有极高的要求,而使用容器,最大的开销就是网络栈的多层转发:
容器内应用 → 容器内eth0 → veth pair → docker0网桥 → iptables NAT → 宿主机物理网卡 → 外部网络
2、数据安全风险高,Docker 容器的生命周期是短暂的、无状态的,如果容器被不小心删除,很容易导致数据丢失
3、运维复杂度高,主从复制的配置更加复杂,性能监控和调优更加困难。
从复制的配置复杂:
- 容器默认使用桥接网络,每次重启容器 IP 都会变
- 主库 IP 一变,所有从库的复制都会断开,因为在配置文件中写死了IP
- 如果要解决需要在启动的时候 --ip 固定ip
性能监控困难:
- 容器内执行
top命令看到的是宿主机的全部 CPU 和内存,不是容器被限制的资源 - 比如你给容器限制了
-m 4G,但容器内执行free命令看到的还是宿主机的 32G 内存 - 比如MySQL会根据看到的 32G 内存来配置缓冲池(innodb_
buffer_pool_size=24G) - 结果就是 MySQL 实际使用内存超过 4G,被 Cgroup OOM 杀死
性能调优困难,需要同时调整两部分参数:
- Docker 容器参数:
--cpus、-m、--ulimit、--shm-size - MySQL 参数:
innodb_buffer_pool_size、innodb_log_file_size等
四、Docker常用命令
cpp
#看容器整体 CPU,发现CPU没跑满
docker stats cometserver
# 进入容器
docker exec -it cometserver /bin/sh
# 启动htop看线程 按 H 键切换线程视图
htop
------------------------------------------
docker run :创建一个新的容器并运行一个命令
常用选项:
-d, --detach:后台运行容器并打印容器id
--name:指定容器名称
--rm:当容器退出时,自动删除容器
--group-add:为容器用户添加更多用户组
--health-cmd:健康检查命令
docker logs : 获取容器的日志
docker start :启动一个或多个已经被停止的容器
docker stop :停止一个运行中的容器
docker restart :重启容器
docker kill :杀掉一个运行中的容器
docker exec :在运行的容器中执行命令
docker top :查看容器中运行的进程信息,支持 ps 命令参数
docker cp :用于容器与主机之间的数据拷贝
docker build 命令用于使用 Dockerfile 创建本地镜像
创建本地镜像流程:
1、在本地写好 Dockerfile,把 所有依赖、配置文件都打包进去
2、构建本地镜像:docker build -t cometserver:v1.0
3、把镜像推送到私有仓库:docker push my-registry/cometserver:v1.0
4、测试环境和生产环境直接拉取这个镜像:docker pull my-registry/cometserver:v1.0
5、解决环境不一致问题
docker images : 列出本地镜像
ocker rmi : 删除本地一个或多个镜像
docker save : 将指定镜像保存成 tar 归档文件