一、自定义镜像与仓库
1 手工创建新镜像
1、基于centos启动容器
[root@vh01 ~]# docker run -it centos bash
2、在容器中配置yum并安装网络管理工具
[root@84ba9248ced0 /]# rm -f /etc/yum.repos.d/*
[root@84ba9248ced0 /]# yum-config-manager --add
http://192.168.4.254/rhel7
[root@84ba9248ced0 /]# echo 'gpgcheck=0' >>
/etc/yum.repos.d/192.168.4.254_rhel7.2.repo
[root@84ba9248ced0 /]# yum install -y net-tools iproute vim-enhanced psmisc openssh-clients bash-completion
3、将修改后的容器保存为镜像
先按ctrl+p+q退出容器。84ba是容器ID,centos:net是新镜像名和tag
[root@vh01 ~]# docker commit 84ba centos:net
4、查看镜像
[root@vh01 ~]# docker images
5、通过新镜像生成容器
[root@vh01 ~]# docker run -it centos:net bash
[root@4cdad189417a /]#rpm -q vim-enhanced
2 通过Dockerfile创建镜像
Dockerfile
• Dockerfile语法格式
– FROM:基础镜像
– MAINTAINER:镜像创建者信息
– EXPOSE:开放的端口
– ENV:设置变量
– ADD:复制文件到镜像
– RUN:制作镜像时执行的命令,可以有多个
– WORKDIR:定义容器默认工作目录
– CMD:容器启动时执行的命令,仅可以有一条CMD
看容器内端口起没起:# docker top ed39b0c55906
ctrl+z bg 后台运行并查看
1、创建工作目录
[root@vh01 ~]# mkdir -p /tmp/docker/simple
[root@vh01 ~]# cd /tmp/docker/simple
2、制作Dockerfile
[root@vh01 simple]# vim Dockerfile
FROM centos:latest # 指定基础镜像
ENTRYPOINT ["/bin/echo"] # 根据此镜像生成的容器启动时运行的命令
3、生成镜像
[root@vh01 simple]# docker build .
4、查看镜像
[root@vh01 simple]# docker images 查看所有的镜像
查看centos:latest镜像层次
[root@vh01 simple]# docker history centos:latest
查看新镜像层次
[root@vh01 simple]# docker history 17df
5、创建容器
[root@vh01 simple]# docker run 17df hello world
hello world
二、使用CMD
通过ENTRYPOINT可以指定容器启动时执行的命令,但是只能运行ENTRYPOINT指定的命令,如果需要指定命令,可以使用CMD来构建镜像
1、新建工作目录
[root@vh01 simple]# mkdir /tmp/docker/simple2
[root@vh01 simple]# cd /tmp/docker/simple2
2、编写Docerfile
[root@vh01 simple2]# vim Dockerfile
FROM centos:latest
CMD ["/bin/echo", "Hello World"]
3、生成镜像
[root@vh01 simple2]# docker build .
4、启动容器
直接启动容器,将运行CMD指定的命令
[root@vh01 simple2]# docker run 528f
指定运行bash程序,覆盖CMD指定的命令
[root@vh01 simple2]# docker run -it 528f bash
三、使用RUN
基于原始镜像执行相关命令,执行命令的结果在新镜像中生效
1、新建工作目录
[root@vh01 simple]# mkdir /tmp/docker/simple3
[root@vh01 simple]# cd /tmp/docker/simple3
2、编写Docerfile
FROM centos:latest
RUN rm -f /etc/yum.repos.d/*.repo
RUN echo -e
"[server]\nname=server\nbaseurl=ftp://172.17.0.1/rhel7.2\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/server.repo
RUN yum install -y iproute net-tools
CMD ["/bin/echo", "hello world"]
3、生成镜像
[root@s62 simple3]# docker build -t mycentos:net .
4、运行容器
[root@vh01 simple3]# docker run 8b86
[root@vh01 simple3]# docker run 8b86 ifconfig
四、使用EXPOSE
EXPOSE用于开放端口
1、新建工作目录
[root@vh01 simple]# mkdir /tmp/docker/simple4
[root@vh01 simple]# cd /tmp/docker/simple4
2、编写Docerfile
[root@vh01 simple4]# vim Dockerfile
FROM centos:latest
RUN rm -f /etc/yum.repos.d/*.repo
RUN echo -e
"[server]\nname=server\nbaseurl=ftp://172.17.0.1/rhel7.2\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/server.repo
RUN yum install -y iproute net-tools httpd
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
3、生成镜像
[root@vh01 simple4]# docker build .
4、运行容器
[root@vh01 simple4]# docker run -d -p 8080:80 d7171c700983
5、访问httpd
在物理主机上访问容器服务 firefox http://192.168.4.1:8080 &
192.168.4.1是安装容器的宿主机
五、使用add
1、新建工作目录
[root@vh01 simple]# mkdir /tmp/docker/simple5
[root@vh01 simple]# cd /tmp/docker/simple5
2、编写Docerfile
[root@vh01 simple5]# vim Dockerfile
FROM centos:latest
RUN rm -f /etc/yum.repos.d/*.repo
RUN echo -e "[server]\nname=server\nbaseurl=ftp://172.17.0.1/rhel7.2\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/server.repo
RUN yum install -y httpd
ADD index.html /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
3、生成镜像
[root@vh01 simple5]# echo 'docker httpd web site test' > index.html
[root@vh01 simple5]# docker build .
4、运行容器
[root@vh01 simple5]# docker run -p 8081:80 -d 5b4270b95dbf
5、访问httpd
在物理主机上访问容器服务 firefox http://192.168.4.1:8081 &
192.168.4.1是安装容器的宿主机
排错:如果在启动容器的时候,提示iptables的相关问题,无法启动容器,可以执行以下操作:
(1)查看iptables是否正常
[root@room8pc30 ~]# iptables -t nat -nL # 如果只看到有限的4个CHAIN,里面又没有规则,说明iptables有误
(2)关闭docker
[root@room8pc30 ~]# systemctl stop docker.service
(3)清空nat表
[root@room8pc30 ~]# iptables -t nat -F
(4)删除docker0网络
[root@room8pc30 ~]# ifconfig docker0 down
[root@room8pc30 ~]# brctl delbr docker0
(5)启动docker
[root@room8pc30 ~]# systemctl start docker.service
(6)查看iptables,如果发现多出了很多规则,意味着已经恢复默认配置
[root@room8pc30 ~]# iptables -t nat -nL
查看centos:latest镜像层次
[root@vh01 simple]# docker history centos:latest
创建工作目录--制作Dockerfile--生成镜像--查看镜像--创建容器
镜像优化:
1、每个容器只运行一个进程
2、不要假定容器能够久远保持启动状态
3、使用.dockerignore文件将不需要的文件进行排除。
4、不要完全自己制作镜像,应该使用官方提供的镜像
5、尽量减少镜像的层数。如不要运行多个RUN,而是将多个命令放到一个RUN中执行
运行最小的镜像
# docker run busybox echo Hello World
3 私有仓库
自定义镜像仓库
registry基本概念
• 共享镜像的一台服务器(镜像化的一台服务器)
[root@s62 simple6]# docker stop $(docker ps -aq)
[root@s62 simple6]# docker rm $(docker ps -aq) //清理本地镜像容器
[root@s62 simple6]# docker pull registry
创建私有仓库
方法1
[root@s62 simple6]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.122.2:5000 --registry-mirror=http://aad0405c.m.daocloud.io
方法2
#cat /etc/docker/daemon.json
{
“insecure-registries” : ["192.168.122.2:5000"]
}
[root@s62 simple6]# systemctl daemon-reload(重载配置文件)
[root@s62 simple6]# systemctl restart docker
[root@s62 simple6]# docker run -id -p 5000:5000 registry //启动容器映射端口
[root@s62 simple6]# docker tag a:label 192.168.122.2:5000/a:label //打标签 /镜像a
[root@s62 simple6]# docker push 192.168.122.2:5000/a:label 上传
[root@s62 simple6]# docker rmi 192.168.122.2:5000/a:label //先删除本地镜像
[root@s62 simple6]# docker run -itd 192.168.122.2:5000/a:label
[root@s62 simple6]# firefox http://192.168.122.2:5000/v2/_catalog //查看远程镜像
[root@s62 simple6]#firefox http://192.168.122.2:5000/v2/_catalog /镜像名/tags/list //查看镜像标签
11、测试
(1)创建另一台虚拟机,安装docker
(2)修改docker.service
[root@vh01 simple]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.122.2:5000
(3)重启docer服务
[root@vh02 ~]# systemctl daemon-reload
[root@vh02 ~]# systemctl start docker.service
sys[root@vh02 ~]# systemctl enable docker.service
(4)下载镜像
[root@vh02 ~]# docker pull 192.168.122.2:5000/a:label
4 持久化存储(接偶)
存储卷
卷的概念
• docker容器不保持任何数据
• 重要数据请使用外部卷存储(数据持久化)
• 容器可以挂载真实机目录或共享存储为卷
共享存储基本概念
• 一台共享存储服务器可以提供给所有Docker主机使用
• 共享存储服务器(NAS、SAN、DAS等)
• 如:
– 使用NFS创建共享存储服务器
– 客户端挂载NFS共享,并最终映射到容器中
使用卷实现永久存储
1、准备宿主机目录
[root@vh01 docker]# mkdir /webroot
[root@vh01 docker]# echo 'hello world' > /webroot/index.html
2、启动容器,并挂载卷
[root@vh01 docker]# docker run -itd -v /webroot/:/data -it centos bash
[root@214cabf0eb60 /]# cat data/index.html
[root@214cabf0eb60 /]# echo 'new data' > /data/mytest.txt
[root@vh01 docker]# ls /webroot/
3、练习
基于centos生成新镜像,新镜像运行后,自动启动httpd。web主页位于宿主机的/webroot
[root@vh01 simple7]# vim Dockerfile
FROM centos:latest
RUN rm -f /etc/yum.repos.d/*.repo && yum-config-manager --add ftp://192.168.4.254/rhel7.2 && echo 'gpgcheck=0' >> /etc/yum.repos.d/192.168.4.254_rhel7.2.repo && yum install -y net-tools httpd
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
[root@vh01 simple7]# docker build -t 192.168.4.1:5000/centos:httpd .
[root@vh01 simple7]# docker push 192.168.4.1:5000/centos:httpd
[root@vh02 ~]# mkdir /webroot
[root@vh02 ~]# echo 'httpd web site test' > /webroot/index.html
[root@vh02 ~]# docker run -d -v /webroot/:/var/www/html/ -p 8080:80 192.168.4.1:5000/centos:httpd
[root@room9pc16 ~]# firefox http://192.168.4.2:8080 &
使用共享存储的案例
NFS服务器
• 服务器
– yum -y install nfs-utils
– vim /etc/exports
– systemctl start nfs
• Docker主机
– mount挂载共享
– 运行容器时,使用-v选项映射磁盘到容器中
案例3:NFS共享存储
1. 服务器创建NFS共享存储
1. 共享目录为/content,权限为所有主机rw
2. 客户端挂载共享
1. 将共享目录映射到容器中
创建共享存储,将vh01上容器的卷数据保存到vh02的NFS共享中
1、配置vh02为NFS服务器
[root@vh02 ~]# yum install -y nfs-utils
[root@vh02 ~]# mkdir -m 777 -p /nfsshare/vh01
[root@vh02 ~]# vim /etc/exports
/nfsshare/vh01 192.168.122.*(rw,sync)
[root@vh02 ~]# systemctl enable nfs-server.service
[root@vh02 ~]# systemctl start nfs-server
[root@vh02 ~]# systemctl start nfs
2、配置vh01为NFS客户端
[root@vh01 simple7]# yum install -y nfs-utils
[root@vh01 simple7]# systemctl start nfs
[root@vh01 simple7]# mkdir /docker_vol
[root@vh01 simple7]# mount 192.168.122.2:/nfsshare/vh01 /docker_vol/
[root@vh01 simple7]# cp -r /webroot/ /docker_vol/
[root@vh01 simple7]# docker run -d -v /docker_vol/webroot/:/var/www/html -p 8088:80 192.168.122.2:5000/a:label
[root@room9pc16 ~]# firefox http://192.168.122.1:8088 &
[root@s62 ~]# docker inspect -f {{.NetworkSettings.IPAddress}} $(docker ps -q) //查看容器IP
[root@s62 ~]# docker run -d -v /var/webroot:/var/www/html a //-v 宿主机源目录:容器内目录
通过centos 基础境像制作一个新的镜像
配置yum
安装ifconfig
安装openssh-server httpd
设置sshd和httpd在运行容器时默认开启
通过root(密码123456)和ssh服务 可以远程连接容器
可以远程访问web
多台web共享数据 局域网内共享
物理机:
#mkdir /chroot
#yum -y install nfs-utils
#vim /etc/exports
/chroot 192.168.4.0/24(rw)
#systemctl start nfs
#ls -R/abc:
Dockerfile rh7.repo(yum仓库) run.sh
#vim Dockerfile
FROM centos
MAINTAINER wangshu [email protected]
RUN rm -rf /etc/yum.repos.d/*
ADD rh7.repo /etc/yum.repos.d/rh7.repo
RUN yum clean all
RUN yum repolist all
RUN yum -y install net-tools psmisc httpd openssh-server
RUN echo 123456 | passwd --stdin root
EXPOSE 22
EXPOSE 80
ADD run.sh /usr/sbin/run.sh
CMD ["/usr/sbin/run.sh"]
#vim run.sh
#!/bin/bash
EnvironmentFile=/etc/sysconfig/sshd
/usr/sbin/sshd-keygen &>/dev/null
/usr/sbin/sshd
EnvironmentFile=/etc/sysconfig/httpd
/usr/sbin/httpd -DFOREGROUND
#chmod 755 run.sh
#echo aaa > /chroot/index.html
#docker build -t myos .
#docker run -d -p 80:80 -p 10022:22 -v /chroot:/var/www/html myos
Docker网络架构
Linux网桥
docker网络
查看 docker 网络结构
docker network ls
创建一个网桥
docker network create --driver bridge --subnet=192.168.1.0/24 br1
查看某一个桥的详细信息
docker network inspect 网桥id
创建一个容器,使用新建的网桥
docker run -it --network=br1 myimg /bin/bash
一、容器间名称自动发现
1、启动一个名字为web1的容器
[root@vh01 simple7]# docker run -itd --name web1 centos
2、启动一个字字为lb的容器,与web1关联
[root@vh01 simple7]# docker run --link web1:web1 --name lb -it centos
[root@e4929b02e94c /]# ping web1
[root@e4929b02e94c /]# cat /etc/hosts
二、跨宿主机容器间通信
1、将vh02的docker0 ip地址改为172.18.0.1/16
[root@vh02 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.122.2:5000 --bip=172.18.0.1/16
[root@vh02 ~]# systemctl daemon-reload
[root@vh02 ~]# systemctl restart docker.service
[root@vh02 ~]# ifconfig docker0
2、在两台宿主机上配置静态路由
[root@vh01 simple7]# route add -net 172.18.0.0 netmask 255.255.0.0 gw 192.168.122.1
[root@vh02 ~]# route add -net 172.17.0.0 netmask 255.255.0.0 gw 192.168.122.2
3、在两台宿主机上启动容器测试网络连通性
[root@vh02 ~]# docker run -it 192.168.122.2:5000/a:label bash
[root@vh01 ~]# docker run -it a bash
[root@vh02 ~]# docker run -it 192.168.122.2:5000/a:label bash
[root@1b3aa8ff4602 /]# ip addr show
[root@1b3aa8ff4602 /]# ping 172.18.0.2
给容器添加网卡的操作:
nspid=$(docker inspect -f '{{.State.Pid}}' conid)
ip link add lnet0 type veth peer name rnet0
ip link set dev lnet0 master br0
ip link set dev lnet0 up
ip link set dev rnet0 name eth1 netns ${nspid}
ln -s /proc/${nspid}/ns/net /var/run/netns/${nspid}
ip netns exec ${nspid} ip link set dev eth1 up
ip netns exec ${nspid} ip addr add 192.168.1.100/24 brd 192.168.1.255 dev eth1
553 docker run -it centos bash
554 docker ps
555 docker run -it d8c6e97555b1 bash
556 docker run -it 8761b27e2f41
557 ifconfig docker0
558 brctl show
559 cd /etc/sysconfig/network-scripts/
560 ls
561 brctl addbr br1
562 brctl show
563 ls
564 docker pss
565 docker ps
566 docker rm -f d8c6e97555b1 a8aeec719f20 8761b27e2f41
567 docker ps
568 ip addr del eth0:1
569 ip addr del 192.168.4/24 eth0:1
570 docker run -it a /bin/bash
571 brctl show
572 ifconfig veth716a582
573 docker run -it a /bin/bash
574 brctl delif docker0 veth716a582
575 docker ps
576 docker attach a1
577 brctl addif docker0 veth716a582
578 docker attach a1
579 docker attach a1ad0643b2c5
580 iptables-save
581 docker network list
582 docker network -h
583 ip a s docker
584 ip a s docker0
585 brctl show
586 brctl show docker0
587 docker ps
588 docker attach a1ad0643b2c5
589 docker inspect -f {{.State.Pid}} a1ad0643b2c5