标签:网络模式 enabled 创新 F12 创建者 sign 缓存 bash命令 版本号
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用及依赖包到一个可移植的容器中,然后发布到任何流行的linux机器上,也可以实现虚拟化。容器是完全使用沙盒机制,相互之间不会有任何接口(类似iphone的app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包装系统。
扩展:沙盒
沙盒也叫沙箱,英文sandbox。在计算机领域指一种虚拟技术,且多用于计算机安全技术。安全软件可以先让它在沙盒中运行,如果含有恶意行为,则禁止程序进一步运行,而不会对系统造成任何危害。
Docker是docColud公司开源的一个基于LXC的高级容器引擎,源代码托管在Github上,基于go语言开发并遵从Apache2.0协议开源。
Docker让开发者可以打包他们的应用及依赖包到一个可移植的container中,然后发布到任何流行的linux机器上。
Docker的创新:Docker镜像一次构建,到处运行。(我们经常遇到一些软件在一个系统平台上可以使用在另一个平台系统上不能使用的情况,如office2016在XP系统上不能使用,在win7或更高版本的windows系统上可以正常使用,又如googe浏览器以后4.9版本就只能在win7或更高版本的windows系统上可以正常使用。mk.rpm在redhat系列的Linux上运行,但是不能在其他的linux版本上运行等)
扩展:
LXC为Linux Container的简写。Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。
LXC主要通过来自kernel的namespace实现每个用户实例之间的相互隔离,通过cgroup实现对资源的配额和度量。
Docker的官网:https://www.docker.com
理解:docker服务相当于鲸鱼,container容器就是集装箱。
container:集装箱,容器
docker:码头工人
docker源代码:https://github.com/moby/moby
扩展:
集装箱是海上运货的一个创新
相同点:docker容器技术和虚拟机技术,都是虚拟化技术。
总结:相对于VM虚拟机,docker少了虚拟机操作系统这一层,所以docker效率比虚拟机高,docker在上启动一个实例一般只要几秒钟
工作流程:服务器A上运行docker Engine服务,在docker Engine上启动很多容器container,从外网Docker Hub上把image操作系统镜像下载下来,放到container容器运行。这样一个容器的实例就运行起来了。
最后,通过Docker client对docker容器虚拟化平台进行控制。
dockerhub:dockerhub是docker官方的镜像存储站点,其中提供了很常见的镜像供用户下载,如ubuntu,centos等系统镜像。通过dockerhub用户也可以发布自己的docker镜像,为些用户需要注册一个dockerhub的账号,在网站上创建一个docker仓库。
Docker核心技术
1.Namespace 实现Container的进程、网络、消息、文件系统和主机名的隔离。
2.Cgroup 实现对资源的配额和度量。
注:Cgroup的配额,可以指定实例使用的CPU的个数,内存大小等,就如下图,vmware虚拟机中的硬件配置参数。
文件系统隔离:每个进程容器运行在一个完全独立的根文件系统里。
资源隔离:系统资源,像CPU和内存等可以分配到不同的容器中,使用cgroup。
网络隔离:每个进程容器运行在自己的网络空间,虚拟接口和IP地址。
日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索和批量检索。
变更管理:容器文件系统的变更可以提交到新的镜像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。
交互式shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell。
Docker的优点:
1.一些优势各VM一样,但是不是所有都一样。
比VM小,比VM快,Docker容器的尺寸减小相比整个虚拟机大大简化了分布到云和从云分发时间和开销。Docker启动一个容器实例的时间很短,一两秒就可以启动一个实例。
2.对于在笔记本电脑,数据中心的虚拟机,以及任何的云上,运行相同的没有变化的应用程序,IT的发布速度更快。
Docker是一个开放的平台,构建,发布和运行分布式应用程序。
Docker使应用程序能够从组件组装和避免开发与生产环境之间的摩擦。
3.可以在部署在公司局域网和云或虚拟机上使用它。
4.开发人员并不关心具体哪个Linux操作系统。
使用Docker,开发人员可以根据所有的依赖关系构建相应的软件,针对他们所选择的操作系统。
然后,在部署时一切是完全一样的,因为一切都在DockerImage的容器上运行。
开发人员负责并且能够确保所有的相关性得到满足。
5.Google、微软、亚马逊,IBM等都支持Docker。
6.Docker支持Unix/Linux操作系统,也支持Windows或Mac
Docker的缺点局限性:
1.Docker用于应用程序是最有用的,但并不包含数据。日志,跟踪和数据库等通常应放在Docker容器外。一个容器的镜像通常很小,不适合存大量数据,存储可以通过外部挂载的方式使用。比如使用:NFS,ipsan,MFS等,-v映射磁盘分区。
一句话:docker只用于计算,存储交给别人
oracle 不适合使用 docker来运行,太大了,存储的数据太多。
docker有以下3种安装方式:
yum install docker
yum install docker-engine
yum install docker-ce
说明:
Docker最早的版本名是docker和docker-engine,现在的名字是docker-ce和docker-ee
2017年年初,docker公司将原先的docker开源项目改名为moby。
moby是继承了原先的docker的项目,是社区维护的开源项目,谁都可以在moby的基础上打造自己的容器产品。
docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品。
docker-ee是docker公司维护的闭源产品,是docker公司的商业产品。
注:moby是源代码,docker-ce和docker-ee是容器产品,是rpm包。
所以现在我们经常使用到的是版本是docker-ce版本。
实验1:部署docker容器虚拟化平台
实验环境:CentOS7.6 64位 IP:172.20.77.201
安装docker环境依赖
[root@server ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
配置国内docker的yum源(阿里云)
[root@server ~]# wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker-ce
[root@server ~]# yum install -y docker-ce docker-cli containerd.io
注:docker-ce-cli 作用是docker命令行工具包。
containerd.io作用是容器接口相关包。
yum info软件包的命令,可以查看一个包的具体作用。
启动docker并加入开机启动项
[root@server ~]# systemctl start docker&&systemctl enable docker
[root@server ~]# docker version #显示docker版本信息
[root@server ~]# docker info #查看docker信息(确认服务运行)显示docker系统信息,包括镜像和容器数。
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.12
Storage Driver: overlay2
Backing Filesystem: xfs
.......
Name: server.com
ID: SSLG:MZG6:THPP:GWBN:7BYC:33KD:PS2G:NGWL:NMN7:S4UL:7LSN:GTQW
Docker Root Dir: /var/lib/docker #默认的docker的家目录,后期镜像也在这个目录下
Debug Mode: false
Registry: https://index.docker.io/v1/ #默认去这个index.docker.io/v1/网站找docker镜像
搜索镜像images
[root@server ~]# docker search centos #从Docker Hub中搜索符合条件的镜像。
星数反映受欢迎的程度,如果OFFICIAL为【OK】,说明为官方提供可以放心使用。
下载镜像方法:
方法1.从公网docker hub拉取(下载)image pull:拉
[root@server ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
6910e5a164f7: Pull complete
Digest: sha256:4062bbdd1bb0801b0aa38e0f83dece70fb7a5e9bce223423a68de2d8b784b43b
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
#如果因为网络问题下载报错了,可以选择换一个dokcer镜像下载地址
方法2:使用阿里云docker镜像加速器,提升pull的速度:
你只需要登录容器Hub服务 https://cr.console.aliyun.com的控制台,使用你注册的阿里云账号,第一次登录时,需要设置一个独立的密码,左侧的加速器帮助页面就会显示为你独立分配的加速地址。
网易镜像:
https://c.163.com/hub#/m/home/ #需要先注册登录上,才能打开此站点
创建配置文件daemon.json
[root@server ~]# vi /etc/docker/daemon.json #需要手动创建daemon.json文件。
写入以下内容:
{
"registry-mirrors":["https://hab0i5dh.mirror.aliyuncs.com"]
}
镜像源可以添加多个,根据自己的网络环境选择速度快的。
[root@server ~]# vi /etc/docker/daemon.json #在文件中插入
{
"registry-mirrors":["https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com""https://hab0i5dh.mirror.aliyuncs.com"]
}
说明:azk8s.cn 这域名是上海蓝云网络科技有限公司的。
上海蓝云网络科技有限公司成立于2013年3月,由世纪互联专门为在中国境内提供Windows Azure和Office365服务而成立,为世纪互联的全资子公司
[root@server ~]# systemctl daemon-reload
[root@server ~]# systemctl restart docker
[root@server ~]# docker info
......
Registry Mirrors:
https://dockerhub.azk8s.cn/ #上海蓝云镜像源
http://hub-mirror.c.163.com/ #网易镜像源
https://hab0i5dh.mirror.aliyuncs.com/ #阿里云镜像源
Live Restore Enabled: false
方法3:把以前下载好的image镜像导入image:
把docker-centos-httpd.tar 镜像上传到linux上
参数: -i docker-centos-httpd.tar 指定载入的镜像归档。
[root@server ~]# docker load -i /root/docker-centos-httpd-image.tar
方法4:直接下载其它站点镜像
[root@server ~]# docker pull hub.c.163.com/library/tomcat:latest
总结:下载docker镜像的4种方法
1、docker pull 直接下载
2、配置成阿里、网易、蓝云的docker加速地址
3、直接导入本地的docker镜像
4、直接下载其它站点的镜像
查看到下载到本地的镜像images列表
[root@server ~]# docker images #列出本地所有镜像。其中[name]对镜像名称进行关键词查询。
REPOSITORY TAG IMAGE ID CREATED SIZE
cent httpd-v2 79d4dad2805d 7 days ago 317MB
centos latest 831691599b88 5 weeks ago 215MB
hub.c.163.com/library/tomcat latest 72d2be374029 2 years ago 292MB
注:docker镜像相当于对程序+程序依赖的库打了一个包
软件是依赖操作系统中的库或二进制文件。如果我把软件所依赖的库和二进制文件打包在一起发布,不用物理机系统上的文件,也就不依赖操作系统了。
开户网络转发功能,默认会自动开启。
手动开启:
[root@server ~]# vi /etc/sysctl.conf #插入以下内容
net.ipv4.ip_forward = 1
[root@server ~]# sysctl -p #生效
net.ipv4.ip_forward = 1
[root@server ~]# cat /proc/sys/net/ipv4/ip_forward
1
否则,docker启动实例时,会报错以下警告:
[root@server ~]# docker run -it centos:latest /bin/bash
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@server ~]# systemctl stop firewalld && systemctl disable firewalld #关闭防火墙
[root@server ~]# systemctl restart docker #关了防火墙,要把docker服务重启一下,不然docker的ip包转发功能无法使用。即使防火墙关了,docker依然会调用内核模块netfilte增加规则,所以有防火墙规则。
1.运行一个container并加载镜像centos,运行起来这个实例后,在实例中执行/bin/bash命令
docker 常用参数:
run 运行
-i 以交互模式运行容器,通常与-t同时使用;
-t 为容器重新分配一个伪终端,通常与-i同时使用;
[root@server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 831691599b88 5 weeks ago 215MB
[root@server ~]# docker run -it centos:latest bash #启动一个实例,也就2秒左右
[root@44087d4632cf /]# ls #查看实例环境
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@44087d4632cf /]# cat /etc/redhat-release #查看实例centos的版本
CentOS Linux release 8.2.2004 (Core)
[root@44087d4632cf /]# exit #退出容器
2.在container中启动一个长久运行的进程,不断向stdin输出hello world。模拟一个后台运行服务
docker常用参数:
-d 后台运行容器,并返回容器ID
-c 后面跟待完成的命令
[root@server ~]# docker run -d centos:latest /bin/bash -c "while true;do echo hello world;sleep 1;done"
5735dd82dc879fecd653acabaee40bd6df129c58dc16b77e9625d680f13eb2de #容器的ID
从一个容器中取日志,查看输出的内容,可用于后期检查docker实例在标准输出中弹出的错误信息或正常的信息。
命令语法: docker logs 容器实例的Name/ID
[root@server ~]# docker logs 5735dd82dc879 #容器的ID可以写全,也可以不写全,只要唯一就行
hello world
hello world
hello world
hello world
查看正在运行的容器:
[root@server ~]# docker ps #列出所有正在运行中的容器
也可以使用短ID或docker实例的名字查看日志输出:
[root@server ~]# docker logs 5735dd82dc87
或
[root@server ~]# docker logs eager_hellman
[root@server ~]# docker ps -a #-a列出所有容器(包含沉睡/退出状态的容器)
3.杀死一个容器。比如:杀死一个正在后台运行的容器
查看要杀死的容器的ID:
[root@server ~]# docker ps -a
杀死ID为5735dd82dc87的容器
[root@server ~]# docker kill 5735dd82dc87
5735dd82dc87
查看结果:
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4.启动、停止、重启container容器实例
[root@server ~]# docker run -d centos:latest /bin/bash -c "while true;do echo hello world;sleep 1;done"
0d3ef5eb705f676da32090dfa8ac0aad6e88a67d9200b3c1c4469d84bbb93dda
[root@server ~]# docker ps #查看容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d3ef5eb705f centos:latest "/bin/bash -c ‘while…" 27 seconds ago Up 26 seconds affectionate_cori
[root@server ~]# docker stop 0d3ef5eb705f #关闭容器
0d3ef5eb705f
[root@server ~]# docker ps #查看容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server ~]# docker start 0d3ef5eb705f #启动容器
0d3ef5eb705f
[root@server ~]# docker restart 0d3ef5eb705f #重启容器
0d3ef5eb705f
删除指定容器container:rm
[root@server ~]# docker rm 0d3ef5eb705f
Error response from daemon: You cannot remove a running container 0d3ef5eb705f676da32090dfa8ac0aad6e88a67d9200b3c1c4469d84bbb93dda. Stop the container before attempting removal or force remove
解决办法:先把容器0d3ef5eb705f关闭然后再删除,或者加-f强制删除
[root@server ~]# docker rm -f 0d3ef5eb705f
0d3ef5eb705f
Docker Image的制作方法:
方法1:docker commit #保存container的当前状态到image后,然后生成对应的image
方法2:docker build #使用Dockerfile文件自动化制作image
[root@server ~]# docker run -it centos:latest /bin/bash
[root@3dcd9a9b467c /]# yum -y install httpd #在container中安装apache软件包
[root@3dcd9a9b467c /]# exit
[root@server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 831691599b88 5 weeks ago 215MB #当前中有一个image centos
根据容器当前状态做一个image镜像:创建一个安装了apache的centos镜像
语法:docker commit <container的ID> <新的image_name>
例:
查看容器ID:
[root@server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED
3dcd9a9b467c centos:latest "/bin/bash" 11 minutes ago
[root@server ~]# docker commit 3dcd9a9b467c centos:httpd
sha256:a460b81d2b70c9c72bae6fce8b93baaa70743130d86477d45ffa691b4668126f
[root@server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos httpd a460b81d2b70 About a minute ago 255MB
centos latest 831691599b88 5 weeks ago 215MB
使用新创建centos:httpd镜像,生成一台容器实例:
[root@server ~]# docker run -it centos:httpd /bin/bash
[root@eaf8b8fda890 /]# rpm -qa httpd #查看是否己经安装好httpd命令
httpd-2.4.37-21.module_el8.2.0+382+15b0afa8.x86_64 #说明是基于centos:httpd镜像创建的容器成功
通过docker build创建一个基于centos的httpd web服务器镜像。
使用docker bulid创建镜像时,需要使用Dockerfile文件自动化制作image镜像
注:Dockerfile有点像源码编译时的./configure后生成的Makefile
1.创建工作目录
[root@server ~]# mkdir /docker-build
[root@server ~]# cd /docker-build/
[root@server docker-build]# touch Dockerfile #make自动化编译时需要Makefile文件,自动化创建docker镜像时,需要Dockerfile
2.编辑Dockerfile
Dockerfile用来创建一个自定义的image,包含了用户指定的软件依赖等。
FROM centos:7.6.1810 #FROM基于哪个镜像
MAINTAINER <root@server.com> #MAINTAINER 镜像创建者
RUN yum install -y httpd #RUN 安装软件用
ADD start.sh /usr/local/bin/start.sh #ADD将文件<src>拷贝到新产生的镜像的文件系统对应的路径。所有拷贝到新镜像中的文件和文件夹权限为0755,uid和gid为0
ADD template /var/www/html
CMD /usr/local/bin/start.sh #当docker实例启动成功后,会执行CMD后面的命令。所以CMD后面一般跟需要开机启动的服务或脚本。一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD
3.创建start.sh脚本启动httpd服务和apache默认首页index.html文件
[root@server docker-build]# echo "/usr/sbin/httpd -DFOREGROUND" > start.sh
[root@server docker-build]# chmod a+x start.sh
上传站点模板
[root@server ~]# rz
#解压模板
[root@server ~]# unzip -d /docker-build/ /root/template.zip
4.使用命令build来创建新的image
语法:docker build -t 父镜像名:镜像的tag Dockerfile文件所在的路径
-t:表示tage,镜像名
使用命令docker build来创建新的image,并命名为centos:httpd
[root@server ~]# cd /docker-build/
[root@server docker-build]# docker build -t centos:httpd-v1 ./
注:./表示当前目录。另外你的当前目录下要包含Dockerfile
Sending build context to Docker daemon 1.198MB
Step 1/6 : FROM centos:7.6.1810
---> f1cb7c7d58b7
Step 2/6 : MAINTAINER <root@server.com>
---> Running in e5027216fba2
Removing intermediate container e5027216fba2
---> 5d74c4e1d4d6
Step 3/6 : RUN yum install -y httpd
---> Running in 84f1dd43cf82
Loaded plugins: fastestmirror, ovl
........
Step 4/6 : ADD start.sh /usr/local/bin/start.sh
---> d668532981bb
Step 5/6 : ADD template /var/www/html
---> 6d61a775761d
Step 6/6 : CMD /usr/local/bin/start.sh
---> Running in 28ce42ce8449
Removing intermediate container 28ce42ce8449
---> 84875768c29a
Successfully built 84875768c29a
Successfully tagged centos:httpd-v1
查看image列表
[root@server docker-build]# docker images
REPOSITORY TAG MAGE ID CREATED SIZE
centos httpd-v1 84875768c29a 7 minutes ago 321MB
注:docker镜像主要包含的内容有:应用/程序+库/依赖关系包
方法1:save image to TarBall
保存Image到tar包
语法:docker save -o 导出的镜像名.tar 本地镜像名:镜像标签
[root@server docker-build]# docker save -o docker-centos-httpd-image.tar centos:httpd-v1
[root@server docker-build]# ll -h docker-centos-httpd-image.tar
-rw-------. 1 root root 315M Aug 3 03:07 docker-centos-httpd-image.tar
测试:删除镜像centos:httpd-v1并导入刚刚创建的本地镜像docker-centos-httpd-image.tar
[root@server ~]# docker rmi centos:httpd-v1
[root@server ~]# docker images #查看镜像发现己删除
[root@server ~]# cd /docker-build/
[root@server docker-build]# docker load -i docker-centos-httpd-image.tar #导入本地镜像
[root@server ~]# docker images #查看镜像发现前删除centos:httpd-v1又回来了
方法2:Push Image To Docker Hub 发布到外网
1、Signup on docker hub&create repo 注册一个账号
http://hub.docker.com/
2、Login to docker hub 登录Docker hub网站
#docker login -u username -p password username@gmail.com
3、Push image to docker hub #上传镜像
#docker push centos:httpd
4、Pull image from docker hub #下载镜像
#docker pull username/centos:httpd-v1 #用户名/镜像名
[root@server ~]# iptables -F
[root@server ~]# systemctl restart docker
[root@server ~]# docker run -d -p 80:80 centos:httpd-v1
1e3d001cf922442001181d989a8821629decbb4cd1f743a04d7885cc17071d6b
注:-p 物理机的80端口:容器实例的80端口,把容器中的80端口映射到物理机上的80端口
在物理机上查看容器状态:
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e3d001cf922 centos:httpd-v1 "/bin/sh -c /usr/loc…" 4 minutes ago Up 4 minutes 0.0.0.0:80->80/tcp sleepy_meninsky
查看物理机上开启的80代理端口
[root@server ~]# netstat -atunp|grep 80
tcp6 0 0 :::80 :::* LISTEN 24782/docker-proxy
测试网站:http://172.20.77.201
注:现在docker实例运行的网络模式类似于VMware的NAT模式。
访问正在运行的container容器实例
语法:docker exec -it <containerid|name> /bin/bash
查看正在运行的容器ID:
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e3d001cf922 centos:httpd-v1 "/bin/sh -c /usr/loc…" 17 minutes ago Up 17 minutes 0.0.0.0:80->80/tcp sleepy_meninsky
[root@server ~]# docker exec -it 1e3d001cf922 /bin/bash #进入容器
[root@1e3d001cf922 /]# echo "hello world" > /var/www/html/test.html #创建test.html文件
[root@1e3d001cf922 /]# exit
exit
[root@server ~]# curl http://172.20.77.201/test.html #物理机上测试查看新添加的test.html文件
hello world
查看物理机和容器的网络:
查看容器的IP:
[root@server ~]# docker exec -it 1e3d001cf922 /bin/bash
[root@1e3d001cf922 /]# yum install -y net-tools
[root@1e3d001cf922 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
物理机的IP:
[root@server ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
注:相当于虚拟机NAT网络模式
测试网络:
[root@server ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.111 ms
单台docker的网络结构如下:
容器命名语法:docker run -d --name 容器实例名 容器镜像名 要执行的命令
容器重命名语法:docker rename 旧容器名 新容器名
例1:运行一个名字为docker1 的容器
[root@server ~]# docker run -itd --name docker1 centos:7.6.1810 /bin/bash
9a9f745b5f8c0e5d25584754345ab3b65953aed2453cf5c58613b79e1409842a
注:如本地无 centos:7.6.1810的镜你,会自动下载
[root@server ~]# docker ps #查看运行的docker镜像
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a9f745b5f8c centos:7.6.1810 "/bin/bash" 3 minutes ago Up 3 minutes docker1
例2:将docker1重命名为docker2
[root@server ~]# docker rename docker1 docker2
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a9f745b5f8c centos:7.6.1810 "/bin/bash" 6 minutes ago Up 6 minutes docker2
语法:docker run -it --name 容器名 -h 指定主机名 镜像 /bin/bash
例1:
[root@server ~]# docker run -it --name docker3 -h docker66.com centos /bin/bash
注:centos镜像代表centos:latest,没有指定tag标签,默认为latest
[root@docker66 /]# hostname #查看主机名
docker66.com
[root@docker66 /]# exit
设置docker容器开机自动启动
语法:docker run --restart=always -itd --name 容器名 镜像 /bin/bash
参数:--restart=always #在容器退出时总是重启容器。
例:
[root@server ~]# docker run --restart=always -itd --name test1 centos /bin/bash
c3f1c501b664518bc321be85ba7ef39dd1823a1aeeee8bdbc3fa8754ea4928b8
[root@server ~]# systemctl restart docker
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3f1c501b664 centos "/bin/bash" 23 minutes ago Up About a minute test1
扩展:
Docker容器的重启策略如下:
no,默认策略,在容器退出时不重启容器
on-failure,在容器非正常退出时(退出时状态非0),才会重启容器
on-failure:3,在容器非正常退出时重启容器,最多重启3次
always,在容器退出时总是重启容器
unless-stopped,在容器退出时总是重启容器,但是不考虑在docker守护进程启动时就己经停止了的容器。
如果创建时未指定--always,可通过update命令来更新设置
语法:docker update --restart=always 容器ID或名字
[root@server ~]# docker run -itd --name test8 centos /bin/bash
411b1e52afde2f784ae27c5cd89f461904e6470cbe5f46978ecdc31c0958280f
[root@server ~]# docker update --restart=always test8
test8
[root@server ~]# systemctl restart docker #重启docker服务
[root@server ~]# docker ps|grep test8 #设置了开机启动的docker实例会启动,说更新设置成功了
411b1e52afde centos "/bin/bash" About a minute ago Up 39 seconds
Docker通过cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。
cgroup概述:
cgroup是Control Groups的缩写,是Linux内核提供的一种可限制、记录、隔离进程给所使用的物理资源(如CPU、内存、磁盘IO等等)的机制,被LXC、docker等很多项目用于实现进程资源控制。cgroup将任意进程进行分组化管理的Linux内核功能。cgroup本身是提供将进程进行分组化管理的功能和接口基础结构,IO或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。
为什么要进行硬件配额?
当多个容器运行时,防止某容器把所有的有一硬件资源都占用了。(比如一台被黑的容器,有可能把所有的资源都占用)
例:给容器实例分配512权重的cpu配额
[root@server ~]# docker run --help|grep cpu-shares
CPU配额参数:-c, --cpu-shares int CPU shares (relative weight) 在创建容器时指定容器所使用的CPU配额值。cpu-shares的值不能保证可以获得1个vcpu或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。
默认每个docker容器的cpu配额值都是1024.在同一个CPU核心上,同时运行多个容器时,容器的CPU加权效果才能体现出来。
例:两个容器A、B的CPU配额分别为1000和500,结果会怎么样?
情况1:A和B正常运行,在cpu进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。
情况2:分配的结果取决于当时其它容器的运行状态。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的CPU时间片的;比如主机上只运行了一个容器,即使它的CPU配额只有50,它也可以独占整个主机的CPU资源。
cgroups只在多个容器同时争抢同一个CPU资源时,CPU配额才会生效。因此,无法单纯根据某个容器的CPU配额来确定有多少CPU资源分配给它,资源的分配结果取决于同时运行的其他容器的CPU分配和容器中进程运行情况。
例:给容器实例分配512权重的CPU使用配额
参数: --cpu-shares 512
[root@server ~]# docker run -it --cpu-shares 512 centos:7.6.1810 /bin/bash
[root@9f2faed531ae /]# cat /sys/fs/cgroup/cpu/cpu.shares #查看容器CPU权重配额
512
注:后面我们启动多个容器实例,测试一下是不是只能使用512权重配额的CPU资源。单独一个容器,看不出来使用的CPU的比例。因为没有其它docker实例跟此docker实例竞争。
参数:--cpuset可以绑定CPU
对多核CPU的服务器,docker还可以控制容器运行限定使用哪些cpu内核和内存节点,即使用--cpuset-cpus和--cpuset-mems参数。对具有有NUMA拓扑(具有多CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则--cpuset-mems的配置基本上不会有明显效果。
扩展:
服务器架构一般分为:SMP、NUMA、MPP体系结构介绍
从系统架构来看,目前的商用服务器大体可以分为三类:
1、对称多处理器结构(SMP :Symmetric Multi-Processor)例:x86服务器,双路服务器。主板上有两个物理CPU
2、非一致存储访问结构(NUMA:Non-Uniform Memory Access)例:IBM小型机 pSeries690
3、海量并行处理结构(MPP:Massive ParallelProcessing)例:IBM大型机 Z14
为什么要把进程绑定到CPU上?
注:当CPU数量很多时,确实需要绑定进程到CPU上,这样可以减少CPU上下文切换的开销,节约时间。
taskset设定CPU亲和力,taskset能够将一个或多个进程绑定到一个或多个处理器上运行。
参数:
-c,--cpu-list 以列表格式显示或指定CPU
-p,--pid 在己经存在的pid上操作
如:设置只在cpuID是1和2的cpu上运行sshd进程程序。注:第一个cpu的ID是0
[root@server ~]# ps aux|grep sshd
root 6628 0.0 0.2 112756 4316 ? Ss 02:59 0:00 /usr/sbin/sshd -D
[root@server ~]# taskset --cpu-list --pid 1,2 6628
pid 6628‘s current affinity list: 0-3
pid 6628‘s new affinity list: 1,2
如:如何查看某个进程在那个cpuID上运行,例如查看的是PID为1的进程
[root@server ~]# taskset -cp 1
pid 1‘s current affinity list: 0-3
例:物理机一共有4个核心,创建的容器只能用0、1、2这3个核心
[root@server cpuset]# docker run -it --name cpu1 --cpuset-cpus 0-2 centos:7.6.1810 /bin/bash
[root@345dc56e4239 /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-2
[root@345dc56e4239 /]# taskset -cp 1
pid 1‘s current affinity list: 0-2
[root@345dc56e4239 /]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 1.1 0.1 11820 1916 pts/0 Ss 20:33 0:00 /bin/bash
cpu-shares的控制只发生在容器竞争同一个cpu的时间片时有效。
如果通过cpuset-cpus指定容器A的使用cpu0,容器B只是用cpu1,在主机上只有这两个容器使用对应的内核情况,它们各自占用全部的内核资源,cpu-shares没有明显效果。
如果要看到cpu-shares的效果,就将容器A和容器B配上cpuset-cpus值并绑定到同一个cpu上,然后同时抢占cpu资源,就可以看出效果
说明:要测试cpu-shares和cpuset-cpus混合使用运行效果,就需要用到压力测试工具stress来让容器实例把cpu跑满
如果要把4核心的cpu中的第一和第三核心跑满,可以运行stress然后使用taskset绑定stress到CPU ID为0和2上就可以了
扩展:stress命令
概述:linux系统压力测试软件stress。stress可以测试Linux系统cpu/memory/IO/disk的负载。
stress参数说明:
-? 显示帮助信息
-v 显示版本号
-q 不显示运行信息
-n 显示己完成的指令情况
-t --timeout N 指定运行N秒后停止
--backoff N 等待N微秒后开始运行
-c 产生n个进程 每个进程反复不停的计算随机数的平方根,测试cpu
-i 产生n个进程 每个进程反复调用sync(),sync()用于将内存上的内容写到硬盘上,测试磁盘
-m --vm n产生n个进程,每个进程不断调用内存分配malloc()和内存释放free()函数,测试内存
--vm-bytes B 指定malloc时内存字节数(默认256MB)
--vm-hang N 指定在free栈的秒数
-d --hadd n 产生n个执行write和unlink函数的进程
--hadd-bytes B指定写的字节数
--hadd-noclean 不unlink
注:时间单位可以为秒 s,分 m,小时 h,天 d,年 y,文件大小单位可以为K,M,G
安装yum扩展源
[root@server ~]# yum install -y epel-release
[root@server ~]# yum install -y stress
例1:产生2个cpu进程,2个io进程,20秒后停止运行
[root@server ~]# stress -c 2 -i 2 --verbose --timeout 20s
例2:测试cpuset-cpus和cpu-shares混合使用运行效果,通过压力测试工具stress来让容器实例把cpu跑满,当跑满后,观察stress进程会不会跑到其他cpu上运行,如果没有其他cpu上运行,说明cgroup资源限制成功。
创建两个容器实例:docker10和docker20。让docker10和docker20只运行在cpu0t和cpu1上,最终测试一下docker10和docker20使用的百分。实验拓扑图如下图
[root@server ~]# docker run -itd --name docker10 --cpuset-cpus 0-1 --cpu-shares 512 centos:7.6.1810 /bin/bash
f8b7817baaf44d181eaaff7551eb74287fcb32b7f64082e14647edebb403e188
[root@server ~]# docker run -itd --name docker20 --cpuset-cpus 0-1 --cpu-shares 1024 centos:7.6.1810 /bin/bash
282da3cd0534f3804f4a136e962e83ce60960f65fafcf39a214a6411828dadd
测试1:进入docker10,使用stress测试进程是不是只在cpu0,1上运行
[root@server ~]# docker exec -it docker10 /bin/bash
[root@f8b7817baaf4 /]# yum install -y epel-release #安装epel扩展yum源
[root@f8b7817baaf4 /]# yum install -y stress #安装stress命令
[root@f8b7817baaf4 /]# stress -c 2 -v -t 10m #运行2个进程,把两个cpu点满
在物理机另外一个虚拟终端上运行top命令,按数字1键,查看每个cpu使用情况,如下图所示
测试2:进入docker20,使用stress测试进程是不是只在cpu0,1上运行并且docker20上运行的stress使用cpu的百分比是docker10的2倍
[root@server ~]# docker exec -it docker20 /bin/bash
[root@282da3cd0534 /]# yum install -y epel-release
[root@282da3cd0534 /]# yum install -y stress
[root@282da3cd0534 /]# stress -c 2 -v -t 10m
在物理机另外一个虚拟终端上运行top命令,按数字1键,查看每个cpu使用情况,如下图所示,
注:两个容器只在cpu0,1上运行,说明cpu绑定限制成功,而且docker20占用的cpu使用率是docker10的2倍,说明--cpu-shares限制资源成功
docker提供了--cpu-period(周期)、--cpu-quota两个参数控制容器可以分配到的CPU时钟周期。
--cpu-period是用来指定容器对CPU的使用,要在多长时间内做一次秤分配。 指定周期
--cpu-quota是用来指它在这个周期内,最多可以有多少时间片断来跑这个容器。 指定在这个周期中使用多少的时间片
跟--cpu-shares不同的,--cpu-period 和--cpu-quotat是指定一个绝对值,而且没有弹性在里面,容器对CPU资源的使用绝对不会超过配置的值。
cpu-period和cpu-quota的单位为微秒。cpu-period的最小值为1000微秒,最大值为1秒,默认值为0.1秒,cpu-quota的值默认为-1,表示不做控制。
时间换算单位:1秒=1000毫秒;1毫秒=1000微秒
例1 .设置docker实例每1秒只能使用单个CPU的0.2秒时间,可以将cpu-period设置为1000000(即1秒),cpu-quota设置为200000(0.2秒)
[root@server ~]# docker run -it --cpu-period 1000000 --cpu-quota 200000 centos:latest /bin/bash
[root@897131ecd3c8 /]# cat /sys/fs/cgroup/cpu
cpu/ cpu,cpuacct/ cpuacct/ cpuset/
[root@897131ecd3c8 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
1000000
[root@897131ecd3c8 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
200000
[root@server ~]# docker run --help|grep rm
参数: -rm Automatically remove the container when it exits
作用:当容器命令运行结束后,自动删除容器,自动释放资源
应用场景:在某些环境下,可能需要大量的新建docker实例,然后仅仅运行几秒钟或几分钟,然后就彻底删除。如运行单元测试或测试弹性云计算。
例:阿里云,要模拟双11的压力,需要快速创建1万docker实例,每个docker容器实例中都运行ab命令,拼命的访问tmall.com首页,运行1个小时,1小时后自动删除
[root@server ~]# docker run -it --rm --name rm centos:7.6.1810 sleep 5
物理机上查看docker进程
[root@server ~]# docker ps|grep rm
34529b6e0619 centos:7.6.1810 "sleep 5" 2 seconds ago Up 4 second rm
等5秒后再查看
[root@server ~]# docker ps|grep rm #己经自动删除了
Docker提供参数-m,--memory =‘‘限制容器的内存使用量。
例1.允许容器使用的内存上限为128M
[root@server ~]# docker run -it -m 128m centos:7.6.1810
[root@b68b2418f5cf /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
134217728
注:也可以使用stress进行测试
例2:创建一个docker,只使用2个cpu核心,只能使用128M内存
[root@server ~]# docker run -it --cpuset-cpus 0-1 -m 128m centos:7.6.1810 /bin/bash
[root@7a9427e01966 /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
134217728
[root@7a9427e01966 /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1
为什么阿里云平台上,普通的云盘的IO为1000 IOPS,为什么这么小?
假如一台存储为20000T,每个云主机20G,给2000台云主机使用,需要控制一下,防止某台云主机吃光存储的I/O资源
情景:防止某个Docker容器吃光你的磁盘I/O资源
例1:限制容器实例对硬盘的最高写入速度为1MB/s
--device参数:将主机的设备添加到容器
--device-write-bps value #限制此设备上的写速度(bytes per second),单位可以是kb、mb、gb
--device-read-bps value #限制此设备上的读速度(bytes per second),单位可以是kb、mb、gb
例1:启动一个docker,限制此设备上的写速度为1MB/s
[root@server ~]# docker run -it -v /var/www/html:/var/www/html --device /dev/sda:/dev/sda --device-write-bps /dev/sda:1mb centos:7.6.1810 /bin/bash
[root@c01b5315f8c9 /]# time dd if=/dev/sda of=/var/www/html/test.out bs=1M count=30 oflag=direct,nonblock #测试IO限制是否有效
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 30.1154 s, 1.0 MB/s
real 0m30.123s
user 0m0.000s
sys 0m0.359s
注:dd 参数
direct:读定数据采用IO方式,不走缓存,直接从内存写到硬盘上。
nonblock:读写数据采用非阻塞IO方式,优先写dd命令的数据
docker用来做计算,数据存储通过外挂目录的方式来实现
语法:docker run -itd -v /src:/dst centos:7.6.1810 /bin/bash
-v 用来指定挂载目录,冒号:前面的/src为物理机本地目录,冒号:后面的/dst为容器里的目录
例1:把物理机上的/var/www/html映射到docker实例的/var/www/html
docker run -itd -v /var/www/html:/var/www/html centos:7.6.1810 /bin/bash
优点:当docker损坏了,数据还在物理机上,再使用apache镜像启动一个docker实例,并将物理机的目录映射到新的docker就可以了,数据不会丢失
1.Docker有以下4种网络模式:
host模式,使用--net=host指定
container模式,使用--net=container:NAME_or_ID指定。
none模式,使用--net=none指定。
bridge模式,使用--net=bridge指定,默认就是bridge模式
桥接本在物理网网络的目的,是为了局域网内用户方便访问docker实例中服务,不需要各种商品映射即可访问服务。但这样做,又违背容器安全隔离的原则,工作中根据实际情况,合理选择
创建桥设备br0:
[root@server ~]# rpm -ivh /mnt/cdrom/Packages/bridge-utils-1.5-9.el7.x86_64.rpm #桥设备安装包
[root@server network-scripts]# cp ifcfg-ens33 /opt
[root@server network-scripts]# vi ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=69532d74-5b91-48c9-953b-131b2ecd980a
DEVICE=ens33
ONBOOT=yes
IPADDR=172.20.77.201
PREFIX=24
GATEWAY=172.20.77.98
DNS1=172.20.77.98
BRIDGE=‘br0‘ #在文件最后插入这一行,表示把ens33桥接到br0上
生成桥设备br0的配置文件:
[root@server network-scripts]# vi ifcfg-br0 #创建ifcfg-br0文件,并写入以下内容
DEVICE=‘br0‘
NM_CONTROLLED=‘yes‘
ONBOOT=‘yes‘
TYPE=‘Bridge‘
BOOTPROTO=none
IPADDR=172.20.77.201
PREFIX=24
GATEWAY=172.20.77.98
DNS1=114.114.114.114
[root@server network-scripts]# systemctl restart network
测试br0:
[root@server ~]# ifconfig
[root@server ~]# ping baidu.com
PING baidu.com (39.156.69.79) 56(84) bytes of data.
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=52 time=43.2 ms
标签:网络模式 enabled 创新 F12 创建者 sign 缓存 bash命令 版本号
原文地址:https://www.cnblogs.com/happysnowy/p/13358339.html