docker学习笔记
docker是一个开源的引擎,可以为任何的应用创建一个轻量级的,可移植的,自给自足的容器。
特点:
隔离性:使用沙盒技术,每个用户实例之间互相隔离,互不影响。
可度量/可配额:每个用户实例可以按需提供计算资源,所使用的资源可以被计量
移动性:用户可以很方便的复制,移动和重建
安全性:
docker的三个基本概念
镜像(image)
docker镜像是一个只读的模板,可以用来u创建Docker容器。
容器(container))
docker利用容器来运行应用。容器是从镜像中创建的实例,它可以被启动,开始,停止,删除。每个
容器相互隔离,保证安全的平台。可以把容器和镜像的关系比作对象和类的关系。
镜像是只读的,容器是在启动的时候创建一层可以读写的层作为最上层。
仓库(Repository)
仓库是用来存放镜像的地方,可分为可分为公有仓库和私有仓库。
理解这三个概念有助于理解docker的整个的生命周期
实验系统环境:rehel7.2
实验环境:selinux和iptables是disabled
所需rpm包
docker-engine-1.10.3-1.el7.centos.x86_64.rpm
docker-engine-selinux-1.10.3-1.el7.centos.noarch.rpm
docker 容器的常用命令
systemctl start docker 开启docker服务
systemctl stop docker 关闭docker服务
docker info 查看程序是否正常工作
docker load -i ubuntu.tar 导入镜像
docker run -it –name vm1 ubuntu
docker run 命令用来创建容器 -i 是指交互式 -t是tty终端 -d可以打入后台
容器的名字是vm1 ,所使用的镜像是ubuntu
docker attach vm1 连接容器
docker top vm1 查看容器进程
docker ps -a 查看已经创建的容器
docker inspect vm1 查看容器详情
docker stats vm1 查看容器资源使用率
docker diff vm1 查看容器修改
docker stop vm1 停止容器
docker start vm1 启动容器
docker attach vm1 连接容器
docker cp vm1:/test.py: /mnt 将容器内根下的test.py 拷贝的物理机下的mnt
docker exec vm1 ls / 查看容器根目录
docker restart vm1 重启容器
docker pause/unpause vm1 暂停/恢复容器
docker rm vm1 删除容器
docker commit vm1 ubuntu:test 将容器更新为镜像
docker export vm1 > vm1.tar 导出容器
docker import vm1.tar image 导入容器为镜像 image
景象的管理
镜像用来创建容器,是容器的只读模板,默认可以从 docker hub 上下载。docker 的镜像是
增量修改,每次创建新的镜像都会在父镜像上构建一个增量的层,基于 AUFS 技术。
docker search 查询镜像
docker pull 拉取镜像
docker push 推送镜像
docker save ubuntu > ubuntu.tar 导出镜像
docker load -i ubuntu.tar 导入镜像
docker commit 更新镜像
docker rmi 删除镜像
创建镜像:
1.利用现成的镜像进行修改
[root@localhost docker]# docker run -it --name vm1 rhel7 bash
rhel7镜像没有yum源,没有vim,ping ip
bash-4.2# cd /etc/yum.repos.d/
bash-4.2# vi yum.repo
[rhel7.2]
name=rhel7.2
baseurl=http://192.168.122.1/rhel7.2
gpgcheck=0
bash-4.2# yum clean all
bash-4.2# yum repolist
bash-4.2# yum install -y vim
bash-4.2# yum install -y iproute ip命令 /usr/sbin/ip
bash-4.2# yum install -y iputils ping 命令/usr/bin/ping
bash-4.2# [root@localhost docker]#
[root@localhost docker]# docker commit -m yum vm1 rhel7:v1
2.利用dokerfile创建
[root@localhost docker]# mkdir /mnt/docker/
[root@localhost docker]# vim Dockerfile
[root@localhost docker]# cat Dockerfile
FROM rhel7:v1
MAINTAINER wax
ENV HOSTNAME server1
EXPOSE 80
RUN yum install -y httpd
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
[root@localhost docker]# docker build -t rhel7:v2 .
.16cker history rhel7:v2
IMAGE CREATED CREATED BY SIZE COMMENT
9a4d7bee94ff 39 seconds ago /bin/sh -c #(nop) CMD ["/usr/sbin/httpd" "-D" 0 B
e0948s ago bash 92.29 MB yum
0a3eb3fde7fd 3 years ago 140.2 MB Imported from -
测试:
[root@localhost docker]# docker run -d --name apache -p 8080:80 rhel7:v2
[root@localhost docker]# vim index.html
[root@localhost docker]# cat index.html
<h1>docker1</h1>
[root@localhost docker]# docker cp index.html apache:/var/www/html
[root@localhost docker]# curl 172.25.12.250:8080
<h1>docker1</h1>
数据卷管理
docker run 在创建容器时使用 -v 参数可以挂载一个或多个数据卷到当前运行的容器中,-v
的作用是将宿主机上的目录作为容器的数据卷挂载到容器中,使宿主机和容器之间可以共
享一个目录。冒号前面的是宿主机的目录(本地目录不存在docker会自动创建),冒号后面的是容器中的挂载目录
注意:docker commit 时卷中的数据不会被保存。
docker run -it –name vm2 -v /tmp/data2:/data2 ubuntu 读写挂载
docker run -it –name vm3 -v /tmp/data3:/data3:ro ubuntu 只读挂载
[root@localhost Desktop]# docker create --name datavol -v /tmp/data1:/data1 -v
/tmp/data2:/data2:ro ubuntu
24488c0977030252d49cf8cf117f8d77d39ae02d7ef86e04329417fbe237410a
[root@localhost Desktop]# docker run -it --name vm1 --volumes-from datavol ubuntu
root@5e7a8d3a59b2:/# ls
bin data1 dev home lib64 mnt proc run srv tmp var
boot data2 etc lib media opt root sbin sys usr
root@5e7a8d3a59b2:/# cd data1/
root@5e7a8d3a59b2:/data1# cp /etc/passwd .
root@5e7a8d3a59b2:/data1# ls
adduser.conf host.conf login.defs os-release shells
root@5e7a8d3a59b2:/data1# cd /data2
root@5e7a8d3a59b2:/data2# cp /etc/passwd .
cp: cannot create regular file './passwd': Read-only file system
root@5e7a8d3a59b2:/data2# [root@localhost Desktop]#
[root@localhost Desktop]# docker run --rm --volumes-from datavol -v
/tmp/backup:/backup ubuntu tar cf /backup/etc.tar /data1
tar: Removing leading `/' from member names
[root@localhost Desktop]# cd /tmp/backup/
[root@localhost backup]# ls
data1 etc.tar
网络管理
Docker 在启动时会创建一个虚拟网桥 docker0,默认地址为 172.17../16, 容器启动后都会
被桥接到 docker0 上,并自动分配到一个 IP 地址。
修改docker的默认网络配置
1.命令行修改
systemctl stop docker
ip link set dev docker0 down
ip addr del 172.17../24 dev docker0
ip addr add 192.168../24 dev dcoker0
ip link set dev docker0 up
2.文件修改:
cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
vim /etc/systemd/system/docker.service
[Service]
Type=notify
ExecStart=/usr/bin/docker daemon -H fd:// --bip="192.168.12.1/24"
...
systemctl daemon-reload
systemctl start docker
容器的四种网络的模式:
bridge桥接模式、host模式、container模式和none模式
启动容器时可以使用 –net 指定参数,默认是桥接模式。
bridge桥接模式:
简单的说:Docker Daemon 利用veth pair技术可以在宿主机上创建两个虚拟的网络接口设备。
这两个设备是通的(相当于一根网线),无论那端收到网络报文,都会传输到另外的一端。
一端桥接到docker0上,另外一端接到Docker Container所属的namespace下。
这样宿主机和容器就可以通信了。
桥接的模式,容器相当于内网,不具有公有IP,外界不能直接和容器进行通信。可以使用NAT模式,
经过中间实现,但会和宿主机竞争端口。NAT模式由于是在第三层网络上的实现手段,
故影响网络的传输效率。
[root@localhost backup]# docker run -d --name web1 nginx
170eed22fdce0968478f47be7936714b9409f539ea6b631f100db9d5340c2706
[root@localhost backup]# docker inspect web1
[root@localhost backup]# curl 192.168.12.2
[root@localhost backup]# docker run -d --name web2 -p 8000:80 nginx
[root@localhost backup]# netstat -antlpe | grep :8000
[root@localhost backup]# netstat -antlpe | grep :8000
Host网络模式:
host模式可以使用宿主机的IP地址与外界进行通信,也可以使用宿主机的端口进行通信。
简单的说容器和宿主机共同使用IP和端口。
host模式的网络隔离性弱化了,不在拥有隔离,独立的网络栈。
[root@localhost backup]# docker run -d --name web3 --net host nginx
[root@localhost backup]# iptables -t nat -nL
Container网络模式:
container模式可以使容器间共享namespace,简单的说对于同一个服务可以共用一个IP和端口。
这样可以更好的使容器间进行通信。容器可以通过localhost来访问其他的容器,传输效率较高,
节省了网络资源。多个容器形成的整体与宿主机以及其他容器形成隔离。
但并没有改善容器与宿主机以外的通信情况。
[root@localhost backup]# docker run -it --name web4 --net container:web2 ubuntu
root@0884821115e4:/# ip addr show eth0
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c0:a8:0c:03 brd ff:ff:ff:ff:ff:ff
inet 192.168.12.3/24 scope global eth0 与web2的ip一致
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:c03/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# docker -d --name web nginx
[root@localhost ~]# docker run -d --name web nginx
[root@localhost ~]# docker run -it --name vm1 --link web:niginx ubuntu
root@1b75e8ac6097:/# env
root@1b75e8ac6097:/# ping web
PING niginx (192.168.12.2) 56(84) bytes of data.
64 bytes from niginx (192.168.12.2): icmp_seq=1 ttl=64 time=0.161 ms
64 bytes from niginx (192.168.12.2): icmp_seq=2 ttl=64 time=0.083 ms
root@1b75e8ac6097:/# cat /etc/hosts
None模式:
不为容器指定任何的网络环境。
[root@localhost backup]# docker run -it --net none --name vm1 ubuntu
创建一个网络模式为none的容器
root@ff15a70c198d:/# ip addr 该容器只有一个本地接口
root@ff15a70c198d:/# [root@localhost backup]#
[root@localhost backup]# cd /var/run/
[root@localhost run]# ip netns add test 如果没有netns目录可以创建
[root@localhost run]# ip link add name veth0 type veth peer name veth1
相当于建立一根网线
[root@localhost run]# ip link set up veth1
[root@localhost run]# ip link set up veth0
[root@localhost run]# brctl addif docker0 veth0
[root@localhost run]# docker inspect vm1 | grep Pid 查看虚拟机的Pid
"Pid": 9542,
"PidMode": "",
"PidsLimit": 0,
[root@localhost ns]# ln -s /proc/9542/ns/net /var/run/netns/9542
[root@localhost netns]# ip link set veth1 netns 9542
[root@localhost netns]# ip netns exec 9542 ip link set veth1 name eth0
修改namespace的名字
[root@localhost netns]# ip netns exec 9542 ip link set eth0 up
在namespace中启用一个设备
[root@localhost netns]# ip netns exec 9542 ip addr add 192.168.12.100/24
dev eth0
为namespace中的设备指定ip
[root@localhost netns]# ip netns exec 9542 route add default gw 192.168.12.1
为namespace中的设备指定网关
[root@localhost netns]# docker exec vm1 ping 172.25.12.250
PING 172.25.12.250 (172.25.12.250) 56(84) bytes of data.
64 bytes from 172.25.12.250: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.25.12.250: icmp_seq=2 ttl=64 time=0.078 ms