Docker概述
什么是容器
• 容器技术已经成为应用程序封装和交付的核心技术
• 容器技术的核心有以下几个内核技术组成:
– CGroups(Control Groups)-资源管理
– NameSpace-进程隔离
– SELinux安全
• 由于是在物理机上实施隔离,启动一个容器,可以像启动一个进程一样快速
Docker是完整的一套容器管理系统,提供了一组命令,让用户更加方便直接地使用容器技术,而不需要过多关心底层内核技术
Docker特性
Docker优点
• 相比于传统的虚拟化技术,容器更加简洁高效
• 传统虚拟机需要给每个VM安装操作系统
• 容器使用的共享公共库和程序
Docker的缺点
• 容器的隔离性没有虚拟化强
• 共用Linux内核,安全性有先天缺陷
• SELinux难以驾驭
• 监控容器和容器排错是挑战
部署Docker
安装前准备: 需要64位操作系统
至少RHEL6.5以上的版本,强烈推荐RHEL7
关闭防火墙和selinux(如果了解规则,不是必须关,初学者还是关掉)
环境准备:
[root@room1pc27 桌面]# sysctl -w net.ipv4.ip_forward=1
[root@room1pc27 桌面]# iptables -t nat -A POSTROUTING -s 192.168.4.0/24 -o enp1s0 -j MASQUERADE
[root@docker ~]# sysctl -w net.ipv4.ip_forward=0
[root@docker ~]# vim /etc/resolv.conf
nameserver 8.8.8.8
[root@docker ~]# nmcli connection modify eth0 ipv4.method manual ipv4.gateway 192.168.4.254 ipv4.dns 8.8.8.8 connection.autoconnect yes
[root@docker ~]# nmcli connection up eth0
//下载busybox,并进入容器内
[root@docker ~]# docker images
[root@docker ~]# docker pull busybox
[root@docker ~]# docker images
[root@docker ~]# docker run -it busybox
/ # exit
[root@docker docker_images]# docker load < centos.tar
[root@docker docker_images]# docker load < nginx.tar
[root@docker docker_images]# docker load < registry.tar
//在容器中配置yum,并安装net-tools
[root@docker docker_images]# docker run -it centos bash
...# cat >rr.repo< [rhel7]
> name=rhel
> baseurl=http://192.168.4.254/rh7dvd
> enabled=1
> gpgcheck=0
> EE
安装Docker
• 软件包列表:docker-engine
docker-engine-selinux
拷贝到私有yum仓库
[root@docker ~]# vim /etc/yum.repos.d/192.168.4.254_rh7dvd.repo //追加内容
[docker]
name=dpcler
baseurl=file:///root/docker/
enabled=1
gpgcheck=0
[root@docker ~]# createrepo /root/docker
[root@docker ~]# yum -y install docker-engine-*
[root@docker ~]# systemctl enable docker
[root@docker ~]# systemctl start docker;systemctl status docker
Docker镜像
什么是镜像: 在Docker中容器是基于镜像启动的
镜像是只读的,是启动容器的核心
镜像采用联合文件系统,分层设计
使用快照的COW技术,确保底层数据不丢失
镜像应该从官方下载,不要试图自己手工制作
Docker hub镜像仓库: https://hub.docker.com
Docker官方提供公共镜像的仓库(Registry)
docker国内镜像仓库 daocloud 阿里
在仓库中搜索镜像
[root@docker ~]# docker search rhel7
[root@docker ~]# docker search centos
[root@docker ~]# docker search nginx
[root@docker ~]# docker search mysql
Docker基本命令
镜像常用命令
• 命令列表
– docker images //查看镜像列表
– docker history //查看镜像制作历史
– docker inspect //查看镜像底层信息
– docker pull //下载镜像
– docker push //上传镜像
– docker rmi //删除本地镜像
– docker save //镜像另存为tar包
– docker load //使用tar包导入镜像
– docker search //搜索镜像
– docker tag //修改镜像名称和标签
查看当前系统的镜像列表
[root@docker ~]# docker images
REPOSITORY镜像仓库名称 TAG镜像标签 IMAGE ID镜像ID CREATED 创建时间 SIZE大小
1. 查看镜像历史,了解镜像制作过程: 详细参考后面的dockerfile内容
[root@docker ~]# docker history centos
2. 查看镜像底层信息: 了解镜像环境变量、 存储卷、 标签等信息
[root@docker ~]# docker inspect centos
查看某一具体项信息
[root@docker ~]# docker inspect -f {{.RootFS}} centos
3. 删除本地镜像——注意:启动容器时删除镜像会提示错误
[root@docker ~]# docker rmi centos //如果有容器在使用该镜像则无法删除
4.导入、 导出镜像
• 导入镜像(通过tar包文件导入镜像)
[root@docker ~]# docker load < xx.tar
[root@docker ~]# docker images
• 导出镜像(将本地镜像导出为tar文件)
[root@docker ~]# docker save image_name > xx.tar
[root@docker ~]# ls xx.tar
启动镜像
[root@docker ~]# docker images
[root@docker ~]# docker run -it centos bash //启动centos镜像生成一个容器
[root@docker ~]# docker ps //开启另一个终端(查看容器信息)
镜像操作
• 下载镜像(从镜像仓库中下载镜像)
# docker help pull
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
# docker pull rhel7
• 上传镜像(上传镜像到仓库),上传需要有帐号
# docdocker help push
Usage: docker push [OPTIONS] NAME[:TAG]
# docker push rhel7
重命名镜像名称(复制)——为镜像新建tag
[root@docker ~]# docker tag centos:latest centos:basic 或
[root@docker ~]# docker tag centos centos:basic
[root@docker ~]# docker images
如果源镜像没有指定tag,那么系统默认使用latest,如果源镜像没有latest,那么将会报错
容器常用命令
• 命令列表
– docker run //使用镜像启动容器
1、在容器中运行命令
[root@docker ~]# docker run centos ls // 命令在新建的容器中运行,执行结束后,容器也就相应的停止
[root@docker ~]# docker run -it centos bash //开启一个交互式的容器
[root@bbb51ac87b08 /]#exit
2、查看run的帮助
[root@docker ~]# docker help run
3、在后台运行容器
[root@docker ~]# docker run -itd centos bash //放入后台执行
退出容器,但是不想结束容器,按组合键ctrl+p+q
启动容器时,为其指定名字
[root@docker ~]# docker run -itd --name rhel7.2 centos bash
4、列出容器列表 docker ps //查看容器列表
– docker ps 查看正在运行的容器
– docker ps -a 查看所有容器列表
– docker ps -aq 仅显示容器id
– docker stop //关闭容器
– docker start //启动容器
– docker restart //重启容器
6、进入容器docker attach|exec
– docker attach 进入容器,exit会导致容器关闭
– docker exec 进入容器,exit退出时不会关闭容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8f218f2341c centos "bash" 9 minutes ago Up 8 minutes jovial_Pasteur
7e4e51117c40 centos "bash" 5 seconds ago Up 2 seconds pedantic_bard
[root@docker ~]# docker attach b8f
[root@docker ~]# docker exec -it 7e4e bash //在已启动的容器中运行新进程
8、查看容器底层信息docker inspect
[root@docker ~]# docker ps
[root@docker ~]# docker inspect 7e4e
[root@docker ~]# docker inspect -f {{.NetworkSettings}} 7e4e
9、查看容器进程列表docker top
[root@docker ~]# docker top 7e4e
10、删除容器docker rm
– 注意,删除正在运行的容器时会提示错误
[root@docker ~]# docker ps -aq
[root@docker ~]# docker rm 7e4e
关闭所有容器
[root@docker ~]# docker stop `docker ps -q`
[root@docker ~]# docker rm $(docker ps -q) //删除所有的容器
操作容器时,每个容器还有一个名字,可以通过名字进行容器管理,容器的名字通过docker ps查看,最后一个字段即为名字
使用nginx镜像
[root@docker ~]# docker load < nginx.tar
[root@docker ~]# docker run -it nginx
另起一终端
[root@docker ~]# docker ps
[root@docker ~]# docker inspect 6bb
[root@docker ~]# curl -i http://172.17.0.5
[root@docker ~]# docker exec -it 6bb bash
自定义镜像
docker commit
• 使用镜像启动容器,在该容器基础上修改,另存为另一个镜像
[root@docker ~]# docker run -itd centos bash
[root@docker ~]# docker ps
[root@docker ~]# docker exec -it IDs bash
//修改(增删改数据、安装软件、修改配置文件等)
[root@docker ~]# docker commit IDs name:label
[root@docker ~]# docker imagesDockerfile
Dockerfile语法格式
– FROM:基础镜像
– MAINTAINER:镜像创建者信息
– EXPOSE:开放的端口
– ENV:设置变量
– ADD:复制文件到镜像
– RUN:制作镜像时执行的命令,可以有多个
– WORKDIR:定义容器默认工作目录
– CMD:容器启动时执行的命令,仅可以有一条CMD
• 使用Dockerfile工作流程
– mkdir build; cd build
– vim Dockerfile
– docker build -t imagename Dockerfile
• Dockerfile文件案例
[root@docker build]# cat Dockerfile
FROM centos
MAINTAINER docker [email protected]
ENV NAME=docker
ENV environment=test
WORKDIR /var/www/html
ADD test.sh /root/test.sh
RUN mkdir /dockerfile
RUN echo "test" > /dockerfile/file.txt
RUN yum -y install httpd
RUN echo "test" > /var/www/html/index.html
EXPORSE 80
CMD [“httpd", "-DFOREGROUND"]
自定义镜像仓库
registry:共享镜像的一台服务器(镜像化的一台服务器)
自定义私有仓库
• 流程:
– docker pull registry
– vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=ip:5000
– systemctl daemon-reload
– systemctl restart docker
– docker run -id -p 5000:5000 registry
– docker tab 镜像 IP:5000/镜像:label
– docker push IP:5000/镜像:label
• 进入registry容器查看/etc/docker/registry/config.yml
持久化存储
存储卷
卷的概念
• docker容器不保持任何数据
• 重要数据请使用外部卷存储(数据持久化)
• 容器可以挂载真实机目录或共享存储为卷
主机卷的映射
• 将真实机目录挂载到容器中提供持久化存储
[root@docker ~]# docker run -v /data:/data -it centos bash
共享存储
共享存储基本概念
• 一台共享存储服务器可以提供给所有Docker主机使用
• 共享存储服务器(NAS、SAN、DAS等)
• 如:
– 使用NFS创建共享存储服务器
– 客户端挂载NFS共享,并最终映射到容器中
使用共享存储的案例
• 服务器
– yum -y install nfs-utils
– vim /etc/exports
– systemctl start nfs
• Docker主机
– mount挂载共享
– 运行容器时,使用-v选项映射磁盘到容器中
案例3:NFS共享存储
1. 服务器创建NFS共享存储
共享目录为/content,权限为所有主机rw
2. 客户端挂载共享
将共享目录映射到容器中
Docker网络架构
Linux网桥
创建虚拟网卡
• 真实网卡配置文件
– cat /etc/sysconfig/network-scripts/ifcfg-eth0
• 虚拟网卡配置文件
– cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
[root@docker ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
TYPE=Ethernet
BOOTPROTO=static
... ...
NAME=eth0:0
DEVICE=eth0:0
ONBOOT=yes
IPADDR=192.168.4.15
创建虚拟网桥
[root@docker ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
BOOTPROTO=static
... ...
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.4.15
[root@docker ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
... ...
NAME=eth0
DEVICE=eth0
BRIDGE=br0
ONBOOT=yes
IPADDR=192.168.4.15
[root@docker ~]# ~]# brctl show
Docker网络拓扑
查看Docker默认网络模型
• 查看默认Docker创建的网络模型
[root@docker ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
c0ae28d57b18 bridge bridge local 桥接模型
b69d4c0c735f host host local 主机模型
4dc88be13b81 none null local 无网络
[root@docker ~]# ip a s docker0
[root@docker ~]# brctl show docker0
//启动容器会绑定该网桥
使用Docker创建网桥
• 新建Docker网络模型
[root@docker ~]# docker network create --driver bridge test01
[root@docker ~]# docker network list
[root@docker ~]# ip a s
[root@docker ~]# docker network inspect test01
• 查看默认Docker创建的网络模型
– 自定义网段
[root@docker ~]# docker network create --subnet=172.30.0.0/16 test01
使用自定义网桥
• 启动容器,使用刚刚创建的自定义网桥
[root@docker ~]# docker run --network=bridge|host|none ... ...
[root@docker ~]# docker run --network=test01 -id nginx
客户端访问容器内的资源
• 默认容器通过SNAT可以访问外网
• 但外部网络的主机不可以访问容器内的资源
• 端口映射
– 使用端口映射可以实现外部网络访问容器内的资源
[root@docker ~]# docker run -p 8080 80 -id nginx
//如:真实机IP为192.168.4.5,使用-p映射真实机的8080端口到容器中的80端口
[root@client ~]# firefox http://192.168.4.5
总结和答疑
删除容器 问题现象
故障分析及排除删除容器
问题现象
• 删除容器,提示错误:
– docker rm 0cc
Error response from daemon: You cannot remove a running container
0cc385eb6f63373397e678347890914347dc8efa3cef
d809c1ed8c157651a261. Stop the container before attempting removal or use -f
故障分析及排除
• 原因分析
– 问题1:提示error:You cannot remove a running container
• 解决办法
– 问题1:先关闭容器,才能删除容器
提交镜像
问题现象
故障分析及排除提交镜像问题现象
• 推送镜像到registry,提示错误:
[root@docker ~]# docker push centos
The push refers to a repository [docker.io/library/centos]
Put https://index.docker.io/v1/repositories/library/centos/: dial tcp:
lookup index.docker.io on 172.40.1.10:53: read udp
172.40.50.118:43696->172.40.1.10:53: i/o timeout故障分析及排除
• 原因分析
– 问题1:提示The push refers to a repository [docker.io/
library/centos]
• 解决办法
– 问题1:先要修改镜像tag,在可以继续push镜像到registry