CLOUD05 - 自定义镜像及仓库 持久化存储 、 Docker网络架构
一、自定义镜像与仓库
1.1 自定义镜像
1.1.1 docker commit
• 使用镜像启动容器,在该容器基础上修改
• 另存为另一个镜像
1、创建容器
]# docker run -it centos bash
2、修改(增删改数据、安装软件、修改配置文件等)
]# docker exec -it IDs bash
3、创建镜像
]# docker ps -a
]# docker commit 容器ID 镜像名称:标签
1.1.2 Dockerfile
Dockerfile语法格式
– FROM:基础镜像
– MAINTAINER:镜像创建者信息
– EXPOSE:开放的端口
– ENV:设置变量
– ADD:复制文件到镜像
– RUN:制作镜像时执行的命令,可以有多个
– WORKDIR:定义容器默认工作目录
– CMD:容器启动时执行的命令,仅可以有一条CMD
1.使用Dockerfile工作流程
– mkdir build; cd build
– vim Dockerfile
– docker build -t imagename Dockerfile
2.Dockerfile文件案例
2.1 创建一个centos基础镜像,自定义yum源,安装基础软件包
-
FROM centos:latest
-
RUN rm -f /etc/yum.repos.d/*
-
ADD local.repo /etc/yum.repos.d/local.repo
-
RUN yum install -y net-tools psmisc vim
2.2 创建一个默认执行的命令为/usr/bin/python的myos镜像
-
FROM myos:latest
-
CMD ["/usr/bin/python"]
2.3 创建一个httpd镜像
-
FROM myos
-
RUN yum install -y httpd
-
WORKDIR /var/www/html
-
RUN echo "hello nsd1804" >index.html
-
ENV EnvironmentFile=/etc/sysconfig/httpd
-
EXPOSE 80
-
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
2.3.1 利用生成的镜像启动一个容器
DockerFile_http]# docker run -itd 138247d0405f
aab943dcbe632d691d6acfa742c33858ded211e69a4a8b5a153c9b430e52aa77
2.3.2 查看容器的IP地址
DockerFile_http]# docker inspect aab
2.3.3 访问hello world主页面
DockerFile_http]# curl -i 172.17.0.5
2.4 创建sshd镜像
~] # vim /usr/lib/systemd/system/sshd.service //如下命令是通过脚本启动sshd
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
-
FROM myos
-
RUN yum -y install openssh-server
-
RUN echo 123456 | passwd --stdin root
-
RUN sshd-******
-
ENV EnvironmentFile=/etc/sysconfig/sshd
-
CMD ["/usr/sbin/sshd", "-D"]
2.4.1 查看生成的镜像ID,并用这个ID启动一个容器
DockerFile_sshd]# docker images
DockerFile_sshd]# docker run -itd ae3d13662775
2.4.2 通过指定镜像ID启动容器
DockerFile_sshd]# docker run -itd ae3d13662775
2.4.3 查看指定容器的IP地址
DockerFile_sshd]# docker inspect cae
2.4.4 在宿主机上登录容器
DockerFile_sshd]# ssh -X 172.17.0.5
1.2 自定义镜像仓库
1.2.1 registry基本概念
• 共享镜像的一台服务器(镜像化的一台服务器)
1.2.2 服务端创建私有镜像仓库
1.修改server端配置文件
~] # vim /etc/docker/daemon.json
{
“insecure-registries” : [“192.168.1.11:5000”]
}
2.完成配置以后重启 docker 服务
~] # systemctl restart docker
3.启动私有仓库服务
~] # docker run -d -p 5000:5000 registry //运行一个registry的容器,这个容器本质上是一个进程
4.打标记 【因为把镜像上传到私有仓库的时候,只能写镜像名称,所以需要给镜像打上私有服务器地址和端口的标记】
docker tag busybox:latest 192.168.1.11:5000/busybox:latest
docker tag myos:latest 192.168.1.11:5000/myos:latest
docker tag myos:python 192.168.1.11:5000/myos:python
docker tag myos:httpd 192.168.1.11:5000/myos:httpd
5.上传镜像 【上传带有私有服务器地址IP和端口的镜像】
docker push 192.168.1.11:5000/busybox:latest
docker push 192.168.1.11:5000/myos:latest
docker push 192.168.1.11:5000/myos:python
docker push 192.168.1.11:5000/myos:httpd
1.2.3 客户机使用私有镜像源
1. 配置 daemon.json 【同上】
2. 重启服务 systemctl restart docker 【同上】
3. 从私有仓库启动容器 【先从192.168.1.11的私有仓库下载镜像,然后通过下载的镜像直接启动】
Status: Downloaded newer image for 192.168.5.140:5000/myos:sshd
docker run -it 192.168.1.11:5000/busybox
docker run -it 192.168.1.11:5000/myos
docker run -d 192.168.1.11:5000/myos:httpd
4.查看私有仓库有什么样的镜像
curl http://192.168.1.11:5000/v2/_catalog
5.查看私有仓库的镜像有什么样的标签
curl http://192.168.1.11:5000/v2/myos/tags/list
二、持久化存储
2.1 存储卷
2.1.1 卷的概念
• docker容器本身不保持任何数据,因为它是一个进程
• 重要数据请使用外部卷存储(数据持久化)
• 容器可以挂载真实机目录或共享存储为卷
2.1.2 主机卷的映射
将真实机目录挂载到容器中提供持久化存储
[aaa@qq.com ~]# docker run -v /data:/data -it centos bash
2.2 共享存储
2.2.1 共享存储基本概念
• 一台共享存储服务器可以提供给所有Docker主机使用
• 共享存储服务器(NAS、SAN、DAS等)
NAS共享存储案例:
– 使用NFS创建共享存储服务器
– 客户端挂载NFS共享,并最终映射到容器中
2.2.2 使用共享存储的案例
1.容器数据同步需求
现在有一个机房,每个机器上都运行着docker,docker上跑着相同类型的容器。如何实现整个机房所有主机相同类型容器的数据同步
2.拓扑结构
3.实现思路
1.搭建一个NFS服务器,创建一个共享文件夹
2.所有Docker主机挂载NFS共享出来的文件夹
3.将Docker主机的挂载目录映射到容器中
4.实现步骤
4.1 NFS服务端
4.1.1 安装NFS
~]# yum -y install nfs-utils
4.1.2 修改主配置文件
vim /etc/exports
/public *(rw,no_root_squash) //当root用户来访问/public共享文件夹的时候,保留root用户身份。不降权为NFS默认访问用户nfsnobody
4.1.3 启动NFS服务
~]# systemctl start nfs
4.2 Docker主机
1.mount挂载共享
docker]# mount -t nfs 192.168.5.142:/public /mnt/
2.运行容器时,使用-v选项映射磁盘到容器中
mnt ]# docker run -itd -v /mnt/:/var/www/html myos:httpd
ebc18e9c87ad094c12f40734f215d7497ec3a3227fdfec7cbf930417b3972133
3.进入容器查看是否共享
mnt ] # docker exec -it ebc bash
b445a01ed57b /]# cd /var/www/html/
三、Docker网络架构
3.1 Linux网桥
3.1.1 创建虚拟网卡 【虚拟网卡的类型是Ethernet】
• 真实网卡配置文件
– cat /etc/sysconfig/network-scripts/ifcfg-eth0
• 虚拟网卡配置文件
– cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
~] # 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
3.1.2 创建虚拟网桥 【虚拟网桥的类型是Bridge】
• 虚拟网桥配置文件
[aaa@qq.com ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
BOOTPROTO=static
… …
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.4.15
~]# brctl show
3.2 Docker网络拓扑
3.2.1 查看Docker默认网络模型
1.查看默认Docker创建的网络模型
[aaa@qq.com ~]# docker network list //默认有三种网络类型
NETWORK ID NAME DRIVER SCOPE
a42dd2253f2a bridge bridge local bridge 桥接模型
f871513293e5 host host local host 主机模型
74a1a7be181d none null local none 无网络
3.2.2 使用Docker创建网桥
1.创建虚拟交换机
docker network create –driver=bridge –subnet 192.168.100.0/24 test01
3.2.3 使用自定义网桥
1.创建一个新的容器,使用新的交换机
~ ] # docker run -it –network=test01 myos
3.2.4 客户端访问容器内的资源
• 默认容器通过SNAT可以访问外网
• 但外部网络的主机不可以访问容器内的资源
• 端口映射
– 使用端口映射可以实现外部网络访问容器内的资源
1.创建容器,使用宿主机的端口 -p 宿主机端口:容器端口
docker1 ] # docker run -d -p 80:80 -v /var/webroot:/var/www/html 192.168.1.11:5000/myos:httpd //使用-p映射真实机的80端口到容器中的80端口
2.客户端访问
[aaa@qq.com ~]# firefox http://192.168.1.11 //访问的是docker1的IP地址,因为docker1的80端口映射到了容器的80端口,所以访问docker1的80端口就是访问容器的80端口。
四、常见问题
4.1 问题现象
• 推送镜像到registry,提示错误:
[aaa@qq.com ~]# docker push centos //默认是上传到Docker官方网站
The push refers to a repository [docker.io/library/busybox]
f9d9e4e6e2f0: Preparing
unauthorized: authentication required
4.2 故障分析及排除
• 原因分析
– 问题1:提示The push refers to a repository
[docker.io/library/centos]
• 解决办法
– 问题1:先要修改镜像tag,在可以继续push镜像到registry