6.1云原生之Docker

一、初识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 杀死

性能调优困难,需要同时调整两部分参数:

  1. Docker 容器参数:--cpus-m--ulimit--shm-size
  2. MySQL 参数:innodb_buffer_pool_sizeinnodb_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 归档文件
相关推荐
rGzywSmDg1 分钟前
如何在Dev-C++中选择TDM-GCC编译器
linux·jvm·c++
云泽80823 分钟前
笔试算法 - 滑动窗口篇(二):从异位词到最小覆盖子串的通用框架
c++·算法
_wxd66628 分钟前
类与对象 (上) (C++)
c++
小码哥06830 分钟前
一套可复用的打车系统模板,微服务版网约车系统|类似滴滴的打车平台
微服务·云原生·架构·滴滴·打车
梦梦代码精31 分钟前
深度拆解:上门按摩系统如何成为本地生活“到家时代”的新引擎?
docker·小程序·uni-app·开源·生活·开源软件
再战300年41 分钟前
通过docker实现mysql一主多从
mysql·docker·容器
basketball61642 分钟前
并查集基础算法总结 C++ 实现
开发语言·c++·算法
凤凰院凶涛QAQ1 小时前
《C++转Java快速入手系列》String篇:在C++里拼字符串像搬砖,在Java里拼字符串像玩乐高 —— 还是带垃圾回收的那种。
java·开发语言·c++
雪度娃娃1 小时前
Asio——socket的创建和连接
linux·运维·服务器·c++·网络协议