一、自定义镜像与仓库

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-keygen
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基本概念

• 共享镜像的一台服务器(镜像化的一台服务器)

docker容器怎么查看共享目录 docker 共享目录_docker

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

docker容器怎么查看共享目录 docker 共享目录_服务器_02

5.查看私有仓库的镜像有什么样的标签

curl http://192.168.1.11:5000/v2/myos/tags/list

docker容器怎么查看共享目录 docker 共享目录_服务器_03

二、持久化存储

2.1 存储卷

2.1.1 卷的概念

• docker容器本身不保持任何数据,因为它是一个进程
• 重要数据请使用外部卷存储(数据持久化)
• 容器可以挂载真实机目录或共享存储为卷

2.1.2 主机卷的映射

将真实机目录挂载到容器中提供持久化存储

[root@jacob ~]# 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.拓扑结构

docker容器怎么查看共享目录 docker 共享目录_服务器_04

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】

• 虚拟网桥配置文件

[root@jacob ~]# 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创建的网络模型

[root@docker1 ~]# 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

docker容器怎么查看共享目录 docker 共享目录_docker容器怎么查看共享目录_05

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.客户端访问

[root@client ~]# firefox http://192.168.1.11   //访问的是docker1的IP地址,因为docker1的80端口映射到了容器的80端口,所以访问docker1的80端口就是访问容器的80端口。

四、常见问题

4.1 问题现象

• 推送镜像到registry,提示错误:

[root@docker ~]# 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