DOCKER容器对系统资源要求很少,一台主机上可以同时运行数千个Docker容器
Docker通过类似git设计理念的操作来方便用户获取、分发和更新应用镜像、存储复用
Docker通过Dockerfile支持灵活的自动化创建和部署机制,可以提高工作效率,并标准
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度快 | 秒级 | 分钟级 |
性能 | 接近原生 | 较好 |
内存 | MB | GB |
硬盘适应 | MB | GB |
运行密度 | 单台主机支持上千个 | 单台主机支持几个 |
隔离性 | 安全隔离 | 完全隔离 |
迁移 | 优秀 | 一般 |
华为云镜像:华为开源镜像站_软件开发服务_华为云
阿里云镜像:阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区
Docker官网:Empowering App Development for Developers | Docker
一、Docker安装
1、如果之前安装过Docker,需要先进行卸载
sudo yum remove docker docker-common docker-selinux docker-engine
2、初始化系统环境
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
3、安装yum源
wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo
[docker-ce-stable] [docker-ce-stable-debuginfo] [docker-ce-stable-source] [docker-ce-test] [docker-ce-test-debuginfo] [docker-ce-test-source] [docker-ce-nightly] [docker-ce-nightly-debuginfo] [docker-ce-nightly-source] |
yum clean all
yum makecache
4、安装docker
yum install docker-ce -y
5、docker优化
打开阿里云官网 产品-->容器与中间件-->容器与镜像服务ACR-->管理控制台-->镜像工具-->镜像加速器,
加速器地址:https://1kv621rm.mirror.aliyuncs.com
sudo mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://1kv621rm.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
6、设置开机自启动
systemctl enable --now docker.service
7、检查docker
docker info
docker run -d -P nginx
docker ps
二、Docker的基本使用
2.1 docker中的三大概念
l 镜像l 容器l 仓库
镜像(Image):Docker镜像(Image),就相当于是一个root文件系统。比如官方镜像ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系统的root文件系统
容器(Container):Image和Container的关系,就像是面向对象程序设计中的类和实例一样,image是静态的定义,container是image运行时的实体。container可以被create、delete、start、pause、stop等
仓库(Repository)用来保存image的Repostiory.当我们构建好自己的image之后,需要存放在Repository中,当我们需要启动一个images时,可以在Repository中下载下来。
镜像:启动容器的模板
容器:对外提供服务的实例
仓库:保存镜像的地方
常用镜像仓库hub.docker.com
自己的私有仓库,阿里云私有仓库:
2.2 Docker镜像相关命令
2.2.1搜索镜像
命令格式: docker search 镜像名称
docker search mysql
Name:镜像名称 DESCRIPTION:描述 STARTS:收藏个数
OFFICIAL:是否是官方镜像 AUTOMATED:自动构建镜像
2.2.3拉取镜像
docker pull [镜像名称]
docker pull mysql
#镜像层
07aded7c29c6: Already exists
f68b8cbd22de: Pull complete
30c1754a28c4: Pull complete
1b7cb4d6fe05: Pull complete
79a41dc56b9a: Pull complete
00a75e3842fb: Pull complete
b36a6919c217: Pull complete
635b0b84d686: Pull complete
6d24c7242d02: Pull complete
5be6c5edf16f: Pull complete
cb35eac1242c: Pull complete
a573d4e1c407: Pull complet
#镜像ID号(镜像ID号是全球唯一),数字摘要
Digest: sha256:4fcf5df6c46c80db19675a5c067e737c1bc8b0e78e94e816a778ae2c6577213d
#镜像 下载状态
Status: Downloaded newer image for mysql:latest
镜像的全称(镜像的tag)
docker.io/library/mysql:latest
2.4 查看当前系统上的镜像
docker images或则docker images ls
docker images -a
REPOSITORY:镜像名称 TAG:镜像版本号 IMAGE_ID:镜像ID(缩写)
CREATED:镜像生成时间距离现在的时长 SIZE:镜像的大小
注意区分:
docker images 列出本地主机上的镜像
docker ps -a 查看本机所有的容器
2.5获取镜像的详细信息
docker inspect [镜像名称]或镜像id
docker inspect mysql
#参数 -f:格式化输出 -q:只显示镜像ID
docker inspect -f '{{.Id}}' 2fe463762680
sha256:2fe4637626805dc6df98d3dc17fa9b5035802dcbd3832ead172e3145cd7c07c2
获取镜像主机名:docker inspect -f '{{.ContainerConfig.Hostname}}' centos
注意属性信息是有区分大小写的
docker images --digests=true
docker images -q |xargs
阿里云docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/xmuid/chen3888015:[镜像版本号]
docker tag f8f4ffc8092c registry.cn-hangzhou.aliyuncs.com/xmuid/chen3888015:v1
docker hub:docker tag f8f4ffc8092c chen3888015/uid/nginx:v1
docker push registry.cn-hangzhou.aliyuncs.com/xmuid/chen3888015:v1
登录镜像仓库
#格式
docker login
注:默认情况 下,docker login --username=chen3888015登录的是官方仓库 ,如果登录其他docker login registry.xmuid.aliyun.com
docker login --username=chen3888015@aliyun.com registry.cn-hangzhou.aliyuncs.com
Uid2933123
#参数
--username|-u:指定用户名
--password|-p:指定密码
为镜像添加标签
docker.io/library/redis:latest
docker.io:镜像仓库的URL
library:镜像仓库命名空间
redis:镜像名称
latest:镜像版本号
镜像上传
ll /etc/docker
cat ~/.docker/config.json
docker push registry.cn-hangzhou.aliyuncs.com/xmuid/chen3888015:v1
镜像的删除
#格式
docker rmi [镜像名称或者镜像id]
参数 -f强制删除
注:当有容器正在使用镜像时,强制删除镜像,只能删除镜像的所有tag不会删除镜像
docker history 查看构建历史
清空镜像
docker image prune
清空镜像: docker images -q |xargs -I {} rm -rf {}
搜索镜像
-f:过滤输出内容
搜索官方提供的带有Redis关键字的镜像
docker search -f is-official=true redis
docker search -f start=8000 redis
保存镜像(commit):保存正在运行的容器直接为镜像 docker commit [容器id|容器名称]
docker commit -a "cjw commit first times" -m "This is a " -p 26b04a5af4d4 test:v2
保存镜像(import/export):保存正在运行的容器为镜像压缩包
docker export [容器的ID]>[包名称]
docker import [压缩包名称] 镜像名称:tag
docker export 26b04a5af4d4 >docker1.tar
docker import docker1.tar.gz ceshi:v3
保存镜像(save/load):保存镜像为压缩包
docker save [镜像名称|镜像ID] >[包名称]
docker save -o [包名称] [镜像名称|镜像ID]
docker save alpine >apline.tar
docker save ceshi:v3 > v4.tar
docker save -o aline2.tar 14119a10abf4
导入镜像的格式:
docker load < [包名称]
docker load < aline2.tar
注:save/load保存镜像无法自定义镜像名称,save保存镜像时如果使用ID保存则load导入镜像无名称,使用名称导入时才有名称
docker rmi 删除镜像
docker rm 删除容器
保存镜像三种方式的区别
1、expoirt保存的镜像体积要小于save(save保存更完全,export保存会丢掉一些不必要的数据)
2、export可以重命名镜像名称而save则不行
3、save可以保存多个镜像而 export则不行
docker:容器,解决异构环境下的应用部署问题
容器启动的必要条件:容器内至少有一个进程运行在前台
镜像:启动容器的模板
docker容器:容器就是对外提供的一个实例
1、创建容器
#格式 docker run [参数] [镜像名称] [运行容器的启动命令]
参数:-d:以守护进程方式运行一个容器
docker run -d [镜像名称]
docker run -d nginx
docker run 运行流程
1、检查本地是否用指定镜像,如果没有则去对应的仓库下载镜像
2、启动容器,如果指定了命令则使用指定的命令,如果没有则使用默认的命令
3、返回容器id
2、查看本机的容器列表 docker ps,查看当前系统中正在运行的容器列表,-a:查看系统中所有的容器 ,-q仅显示容器的id
container id:容器ID
IMAGE:镜像ID或名称
command:容器启动执行的命令
CREATED:创建的时间
STATUS:状态和时间,up 正常启动,exit:停止
PORTS:容器内应用监听的端口
NAMES:容器的名称,1、如果容器的名称随机生成则不提供docker dns解析,2、如果指定名称,则DNS会解析
3、停止和启动一个容器
#停止
docker stop [容器的id或则名称]
#启动(该容器必须是系统已经存在的容器)
docker start [容器的id或则名称]
-p:指定端口映射
docker run -d -p 30080:80 nginx
docker run -d -p 宿主主机端口:容器内端口 [容器名称] [镜像名称] [cmd]
-P:随机端口映射
-t:创建伪终端
-i:打开标准输出
-v :挂载服务器目录到容器中
--rm:容器生命周期结束时立刻删除
-e:在容器中创建一个环境变量
--name指定容器名称
--link容器之间链接,连接上一个容器,实现网络互通
-h:设置容器主机名
docker run --link 被连接胡容器的名称:连接的别名 [镜像名称] [cmd]
docker run -v 宿机主机目录:容器内目录 【镜像名称】 【cmd]
docker run --rm -d nginx
docker run -v /root:/root -it centos:7 bash
docker run -it nginx bash
docker run -e NAME=cjw -it centos
docker run -it --link cjwei_nginx:nginx centos bash
docker run -it -h "cjwei_server" centos bash
--name:指定容器的名称
docker run -d --name [容器的名称] [镜像名称] [cmd]
docker run -d --name cjw_container_nginx nginx
docker run -it nginx bash
docker run -it centos bash
nginx -g 'ademon off;'
touch {a..z}
touch {1..10}.txt
、
4、删除容器
#格式 -f:强制删除
docker rm [容器名称|ID]
清空所有已经停止状态的容器:docker rm $(docker ps -a -q)
先查看要删除的容器:docker ps -a
停止容器的运行:docker stop cjwei_nginx
删除容器:docker rm cjwei_nginx
注意删除之前最好先停止,否则有可能会报错
Error response from daemon: You cannot remove a running container 0def2a81188ff79dffeed7df4dd116236798f352409a0498dd954518d104b82a. Stop the container before attempting removal or force remove
5、查看容器内容
docker inspect 容器名称 或则id
监控一个docker运行状态?: docker inspect -f '{{.State Running}}' nginx
6、复制命令
复制到容器内:docker cp [宿主主机文件路径] 容器ID:容器内路径
docker cp a.py c3ef6d00a57c:/usr/share/nginx/html
docker run --link cjw_container_nginx:nginx -it centos bash
curl nginx/a.py
服务器到容器外:docker cp 容器ID:容器内路径 [宿主主机文件路径]
docker cp c3ef6d00a57c:/etc/nginx/nginx.conf .
7、进入容器
#进入容器一般有四种
7.1、exec:在容器外向容器内执行一个命令 (相当于自己建了一个进程)
docker exec [容器的名称] [参数]
docker exec cjw_container_nginx ls /usr/share/nginx/html
7.2 attach:缺点在命令结束时,容器也跟着结束了
docker attach 0def2a81188f
7.3nsenter:建立一个管道连接上容器主id
nsenter --target $(docker inspect -f {{.Sate.Pid}} )--mount --uts --ipc --net --pid
7.4 ssh:通过SSH连接
三、Docker网络
3.1网络基础
Docker使用到Linux网络有关的技术分别有:网络名称空间、Veth、网桥、Iptables、路由。
网络名称空间:
net namespace
为了支持网络协议的多个实例,Linux在网络协议栈中引入了网络名称空间(NetworkNamespace),这些独立的协议栈被隔离到不同的命名空间中。处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网络通信,就好像两个”平行宇宙“。通这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境,而Docer正是利用这种网络名称空间的特性,实现了不同容器之间的网络隔离。在Linux的网络命名空间内可以有自己独立的Iptables来转发、NAT及IP包过滤等功能。
Linux的网络协议是十分复杂的,为了支持独立的协议栈,相关的全局变量都必须修改为协议栈私有。最好的办法就是让变量的成员 ,然后为了协议栈的函数调用加入一个Namespace参数。这就是Linux网络名称空间的核心。所有的网络设备都只能属于一个网络名称空间。当然,通常的物理网络设备只能关联到root这个命名空间中。虚拟网络设备则可以被创建并关联到一个给定的命名空间中,而且可以在这些名称空间之间移动。
网络命名空间的创建
[root@orjklp6w ~]# ip netns add test01
[root@orjklp6w ~]# ip netns add test02
[root@orjklp6w ~]# ip netns list
test02
test01
3.1.2Veth设备
引入Veth设备对是为了在不同的网络名称空间之间进行通信tjh用它可以直接将两个网络空间链接起来。由于要连接的两个网络命名空间,所以Veth设备是成对出现的,很像一对以太网卡的网线。并且中间有一根直连的网线。既然是一对网卡,那么我们将其中一端称为另一端的peer。在Veth设备的一端发送数据时,它会将数据直接发送到另一端,并触发另一端的接收操作。
3.2.1生成了两个veth设备,互为对方的peer
ip link add veth type veth peer name veth001
ip link show
3.2.2 绑定命名空间
ip link set veth001 netns test01
ip link show |grep veth
查看对端Veth设备
ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001
ip a|grep 15
为对端Veth设备设置IP
ip addr add 172.16.0.112/20 dev veth
网卡重启
ip link set dev veth down
ip link set dev veth up
3.3网桥
Linux可以支持多个不同的网络,它们之间能名相互通信,就需要一个网桥。网桥是二层的虚拟网络设备,它是把若干个网络接口”连接“起来,从而报文能够互相转 发。网络能够解收发的报文,读取目标MAC地址的信息,和自己记录的MAC表结合。来决定报文的转发目标网口。
网桥设brO绑定了eth0、eth1。对于网络协议㭜的上层来说,只看得到brO.因为桥接是在数据链路层实现的,上层不需要关心桥接的细节,于是协议栈上层需要发送的报文送到brO,网桥设备的代理代码判断报文该被转发到brO还是eth1,或者两者皆转发。反过来,从ethO或从eth1接收到的报文被提交给网桥的处理代码,在这里会判断报文应该被转发、丢弃还是提交到协议枝上层。而有时eth1也有可能会作为报文的源地址或目的地址,直接参与报文的发送与接收,从而绕过网桥。
3.4Iptables
网路协议栈
总结
设备 | 作用总结 |
network namespace | 主要提供了关于网络资源的隔离,包括网络设备、IPV4和IPV6协议栈、IP路由表、防火墙、/pro/net目录、/sys/class/net目录、端口(socket)等 |
linux bridge | 功能相当于物理交换机,为连在其上的设备(容器)转发数据帧,如docker0网桥 |
iptables | 主要为容器提供NAT以及容器网络安全 |
veth pair | 两个虚拟网卡组成的数据通道。在Docker中,用于连接Docker容器和lLinuxBridge。一端在容器中作为eth0网卡,另一端在Linux Bridge中作为网桥的一个端口。 |
3.2Docker网络模式
Docker使用Linux桥接的方式,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址 ,称为Container-IP,同时Docer网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的CONTAINER-ip直接能穿主。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过-p 或-P参数来启用,访问容器的时候就通过【宿主机IP】:【容器端口】访问容器。
Docker网络模型 | 配置 | 说明 |
bridge模式 | ||
host模式 | docker run -it --network=host centos bash | 容器使用宿主主机的网卡,不能跟宿主主机的端口冲突。 |
Containe模式 | docker run -it --network="container:nginx1" centos bash | 一个容器使用另一个容器的网卡。 |
None模式 | docker run -it --network="none" centos bash | |
3.2.1bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在Iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
查看网桥:docker network ls
创建私有网桥:docker network create cjw_bridge
指定链接的网桥: docker run -it --network=cjw_bridge centos bash
查看网桥的信息:
docker network inspect [网桥的名称|ID]
网桥帮助命令:docker network -h
连接网桥:docker network connect -h
docker network connect [网络的名称] [容器的名称]
docker network connect cjw_bridge cjw_nginx
断开某个镜像的连接:docker network disconnect cjw_bridge cjw_nginx
删除一个网桥
docker network rm [网桥名称】
清除所有网桥
docker network purne
3.2.2host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的NetworkNamespace,而是和宿主机共用一个NetworkNamespace,容器将不会虚拟出自己的网瞳,配自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
docker run -it --network=host centos bash
跟服务器是同一个IP
docker run -d --network=host nginx
3.2.3 Containe模式
这个模式指定新创建的容器和已经存在的一个容器共享一个NetworkNamespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围 等。同样两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
docker run -d --name nginx1 nginx
docker run -it --network="container:nginx1" centos bash
3.3.4none模式
使用none模式,Docker容器拥有自己的NetworkNamespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器通过--network=none来指定。这种类型的网络没有办法联网,封半的网络能很好的的保证容器的安全性。
4、DockerFile构建镜像
Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。一般而言,Dockerfile主体内容分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动执行指令
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM,一个声明以#字符开头则视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。
FROM:它的妈妈是谁(基础镜像),指定基础镜像,目的是为了给构建镜像提供一个基础环境。
MAINTAINER:告诉别,你创造了它(维护者信息),指定维护都信息
RUN:你想让它干啥(把命令前面加上RUN),基于docker镜像运行一个指令,将结果反映到新生成的镜像。RUN指令后面执行的指令必须是镜像中存在了的命令。
CMD:指定容器运行的默认命令,ngingx -g "daemon off;"
ADD:往它肚子里放点文件(COPY文件,全自动解压),ADD将本地文件添加到镜像,COPY将本地文件复制到镜像,ADD支持自动解压,但是仅仅支持解压tar包,ADD支持远程下载,但是不会解压下载。
WORKDIR:我是cd,今天刚化了妆(当前工作目录)
EXPOSE:我要打开的门是啥(端口)
Dockerfile是由一行行指令语句构成的一个创建docker镜像的配置文件。
DOCKERFile由三个部分组成,基础镜像(必须的),运行指令,容器默认执行命令。
[root@orjklp6w ~]# mkdir -p docker1 [root@orjklp6w ~]# cd docker1 [root@orjklp6w docker1]# vim Dockerfile [root@orjklp6w docker1]# cat Dockerfile FROM nginx [root@orjklp6w docker1]# docker build -t chenjianwei_nginx:v1 . Sending build context to Docker daemon 2.048kB Step 1/1 : FROM nginx ---> f8f4ffc8092c Successfully built f8f4ffc8092c Successfully tagged chenjianwei_nginx:v1 [root@orjklp6w docker1]# |
docker build -t chenjianwei_nginx:v1 .
dockerfile执行是按照从上到下
如果构建的上个镜像执行过此步骤,下一个则可以使用缓存(using cache)
1、从互联网下载内容不会使用缓存
2、添 加文件内容(ADD、COPY)
如果上一步修改过,则下面的dockerfile步骤全部不使用缓 存。
ENV :设置一个容器的环境变量
ENV COMPUTERNAME=CJWComputer
EXPOSE:指定容器需要向外界暴露的端口,实际上没有暴露,只有指定了EXPOSE才能使用-P
EXPOSE 80
cat Dockerfile
FROM centos:7
ADD epel.repo /root
docker build -t test:v7 .
docker run -it test:v7 bash
docker build -t test:v8 .
cat Dockerfile FROM centos:7 COPY epel.repo /root |
cat Dockerfile FROM centos:7 ADD etcd-v3.5.1-linux-amd64.tar.gz /root |
ADD:将本地文件添加到镜像
ADD:支持自动解压,但是仅仅支持解压tar包
ADD:支持远程下载,但是不会解压下载内容
COPY:将文件复制到镜像
FROM centos:7 ADD https://download.redis.io/releases/redis-6.2.6.tar.gz /opt |
epel | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
epel.repo
[epel-debuginfo] [epel-source] |
docker run -d -P 8080:80 test:v15
docker ps