Docke技术应用
一、理论讲解
A、什么是容器
• 容器技术已经成为应用程序封装和交付的核心技术
• 容器技术的核心有以下几个内核技术组成:
– CGroups(Control Groups)-资源管理
– NameSpace-进程隔离
– SELinux安全
• 由于是在物理机上实施隔离,启动一个容器,可以像启动一个进程一样
B、什么是Docker
• Docker是完整的一套容器管理系统
• Docker提供了一组命令,让用户更加方便直接地使
用容器技术,而丌需要过多关心底层内核技术
C、Docker优点
• 相比于传统的虚拟化技术,容器更加简洁高效
• 传统虚拟机需要给每个VM安装操作系统
• 容器使用的共享公共库和程序
D、Docker的缺点
• 容器的隔离性没有虚拟化强
• 共用Linux内核,安全性有先天缺陷
• SELinux难以驾驭
• 监控容器和容器排错是挑战
F、什么是镜像
• 在Docker中容器是基于镜像启动的
• 镜像是启动容器的核心
• 镜像采用分层设计
• 使用快照的COW技术,确保底层数据打开不丢失
Docker hub镜像仓库
• https://hub.docker.com
• Docker官方提供公共镜像的仓库(Registry)
二、部署Dock
安装Docker
rpm -ivh docker-engine-1.12.1-1.el7.centos.x86_64.rpm
rpm -ivh docker-engine-selinux-1.12.1-1.el7.c
三、镜像操作
• 下载镜像(从镜像仓库中下载镜像): #docker pull centos
• 上传镜像(上传镜像到仓库): #docker push centos
• 导入镜像(通过tar包文件导入镜像): # docker load < xx.tar
• 导出镜像(将本地镜像导出为tar文件):# docker save image_name > xx.tar
• 启动镜像生成一个容器:# docker run -it centos bash
• 重命名镜像名称:# docker tag centos:latest test:v1
镜像常用命令:
四、容器操作
容器常用命令
使用镜像启动容器
[root@jacob ~]# docker run -it centos bash //启动后容器放在前台运行
[root@jacob~]#docker run -itd centos bash //启动后容器放在后台运行
进入容器的三种方法
方法一:
– docker attach 进入容器,exit会导致容器关闭
[root@ms docker]# docker attach fb66c90f5bf9
[root@fb66c90f5bf9 /]# exit
Exit
方法二:
– docker exec 进入容器时后面必须执行一条命令 退出时不会关闭容器
[root@ms docker]# docker exec -it 01a7e3e5f71b bash
[root@01a7e3e5f71b /]# exit
exit
方法三:
–那么通过容器的ID号进入容器
获取容器的pid号:
[root@ms ~]#docker inspect --format "{{.State.Pid}}" fb66c90f5bf9
通过容器的pid号进入容器:
[root@ms ~]# nsenter -t 3974 -u -i -n -p
那么通过容器的ID号进入容器可以编写脚本:
[root@ms docker]# vim ns.sh
#!/bin/bash
Use nsenter to access docker
docker_in(){
NAME_ID=$1
PID=$(docker inspect -f "{{ .State.Pid }}" $NAME_ID)
nsenter -t $PID -m -u -i -n -p
}
docker_in $1
删除容器
删除已经关闭的容器:
[root@ms docker]# docker rm 7313aebddfd7
删除正在运行的容器命令
[root@ms docker]# docker rm -f 7313aebddfd7
利用docker做实验时可以加上--rm参数 容器执行完命令后自动删除:
[root@ms docker]# docker run --rm centos /bin/echo "hehe"
只列出正在运行容器的ID号
[root@ms docker]# docker ps -a
杀死所有正在运行的容器
[root@ms docker]# docker kill $(docker ps -a -q)
五、制作自定义镜像
1.1 问题
本案例要求制作自定义镜像:
基于centos镜像使用commit创建新的镜像文件
基于centos镜像使用Dockerfile文件创建一个新的镜像文件
1.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:使用镜像启动容器
1)在该容器基础上修改yum源
1.[root@docker1 docker_images]# docker run -it centos
2.[root@8d07ecd7e345 /]# rm -rf /etc/yum.repos.d/*
3.[root@8d07ecd7e345 /]# vi /etc/yum.repos.d/dvd.repo
4.[dvd]
5.name=dvd
6.baseurl=ftp://192.168.1.254/system
7.enabled=1
8.gpgcheck=0
9.[root@8d07ecd7e345 /]# yum clean all
10.[root@8d07ecd7e345 /]# yum repolist
2)安装测试软件
1.[root@8d07ecd7e345 /]# yum -y install net-tools iproute psmisc vim-enhanced
3)ifconfig查看
1.[root@8d07ecd7e345 /]# ifconfig
2.eth0: flags=4163
- inet 172.17.0.3 netmask 255.255.0.0 broadcast 0.0.0.0
- inet6 fe80::42:acff:fe11:3 prefixlen 64 scopeid 0x20
- ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
- RX packets 2488 bytes 28317945 (27.0 MiB)
- RX errors 0 dropped 0 overruns 0 frame 0
- TX packets 1858 bytes 130264 (127.2 KiB)
- TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
10.[root@8d07ecd7e345 /]# exit
11.exit
步骤二:另存为另外一个镜像
1)创建新建镜像
1.[root@docker1 docker_images]# docker start 8d07ecd7e345
2.//可以简写为8d,要保证唯一性
3.8d07ecd7e345
4.[root@docker1 docker_images]# docker commit 8d07ecd7e345 myos:v1
5.sha256:ac3f9c2e8c7e13db183636821783f997890029d687b694f5ce590a473ad82c5f
2)查看新建的镜像,如图-1所示:
图-1
3)验证新建镜像
1.[root@docker1 docker_images]# docker run -it myos:v1
2.[root@497c7b4664bf /]# ifconfig
3.eth0: flags=4163
- inet 172.17.0.6 netmask 255.255.0.0 broadcast 0.0.0.0
- inet6 fe80::42:acff:fe11:6 prefixlen 64 scopeid 0x20
- ether 02:42:ac:11:00:06 txqueuelen 0 (Ethernet)
- RX packets 0 bytes 0 (0.0 B)
- RX errors 0 dropped 0 overruns 0 frame 0
- TX packets 7 bytes 578 (578.0 B)
- TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
步骤三:使用Dockerfile文件创建一个新的镜像文件
Dockerfile语法格式:
– FROM:基础镜像
– MAINTAINER:镜像创建者信息(说明)
– EXPOSE:开放的端口
– ENV:设置环境变量
– ADD:复制文件到镜像
– RUN:制作镜像时执行的命令,可以有多个
– WORKDIR:定义容器默认工作目录
– CMD:容器启动时执行的命令,仅可以有一条CMD
1)创建一个Apache的镜像文件
1.[root@docker1 ~]# mkdir oo
2.[root@docker1 ~]# cd oo
3.[root@docker1 oo]# touch Dockerfile //Dockerfile文件第一个字母要大写
4.[root@docker1 oo]# cp /etc/yum.repos.d/local.repo ./
5.[root@docker1 oo]# vi Dockerfile
6.FROM myos:v1
7.RUN yum -y install httpd
8.ENV EnvironmentFile=/etc/sysconfig/httpd
9.WORKDIR /var/www/html/ //定义容器默认工作目录
10.RUN echo "test" > /var/www/html/index.html
11.EXPOSE 80 //设置开放端口号
12.CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
13.[root@docker1 oo]# docker build -t myos:http .
14.[root@docker1 oo]# docker run -d myos:http
15.d9a5402709b26b42cd304c77be442559a5329dc784ec4f6c90e4abac1c88e206
16.[root@docker1 oo]# docker inspect d9
17.[root@docker1 oo]# curl 172.17.0.7
18.test
六:创建私有镜像仓库
2.1 问题
本案例要求创建私有的镜像仓库:
Docker主机:192.168.1.20
镜像仓库服务器:192.168.1.10
2.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:自定义私有仓库
1)定义一个私有仓库
1.[root@docker1 oo]# vim /etc/docker/daemon.json //不写这个文件会报错
2.{
3."insecure-registries" : ["192.168.1.10:5000"] //使用私有仓库运行容器
4.}
5.[root@docker1 oo]# systemctl restart docker
6.[root@docker1 oo]# docker run -d -p 5000:5000 registry
7.273be3d1f3280b392cf382f4b74fea53aed58968122eff69fd016f638505ee0e
8.[root@docker1 oo]# curl 192.168.1.10:5000/v2/
9.{} //出现括号
10.[root@docker1 oo]# docker tag busybox:latest 192.168.1.10:5000/busybox:latest
11.//打标签
12.[root@docker1 oo]# docker push 192.168.1.10:5000/busybox:latest //上传
13.[root@docker1 oo]# docker tag myos:http 192.168.1.10:5000/myos:http
14.[root@docker1 oo]# docker push 192.168.1.10:5000/myos:http
2)在docker2上面启动
1.[root@docker2 ~]# scp 192.168.1.10:/etc/docker/daemon.json /etc/docker/
2.[root@docker2 ~]# systemctl restart docker
3.[root@docker2 ~]# docker images
4.[root@docker2 ~]# docker run -it 192.168.1.10:5000/myos:http /bin/bash
5.//直接启动
步骤二:查看私有仓库
1)查看里面有什么镜像
1.[root@docker1 oo]# curl http://192.168.1.10:5000/v2/_catalog
2.{"repositories":["busybox","myos"]}
2)查看里面的镜像标签
1.[root@docker1 oo]# curl http://192.168.1.10:5000/v2/busybox/tags/list
2.{"name":"busybox","tags":["latest"]}
3.[root@docker1 oo]# curl http://192.168.1.10:5000/v2/myos/tags/list
4.{"name":"myos","tags":["http"]}
七、NFS共享存储
3.1 问题
本案例要求创建NFS共享,能映射到容器里:
服务器创建NFS共享存储,共享目录为/content,权限为rw
客户端挂载共享,并将共享目录映射到容器中
3.2 方案
本方案要求需要一台NFS服务器(NFS用真机代替),ip为192.168.1.254,一台客户端docker1主机,ip为192.168.1.10,一台户端docker2主机,ip为192.168.1.20,实现客户端挂载共享,并将共享目录映射到容器中,docker1更新文件时,docker2实现同步更新,方案如图-2所示:
图-2
3.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:配置NFS服务器
1.[root@room9pc01 ~]# yum -y install nfs-utils
2.[root@room9pc01 ~]# mkdir /content
3.[root@room9pc01 ~]# vim /etc/exports
4./content (rw,no_root_squash)
5.[root@room9pc01 ~]# systemctl restart nfs-server.service
6.[root@room9pc01 ~]# systemctl restart nfs-secure.service
7.[root@room9pc01 ~]# exportfs -rv
8.exporting :/content
9.[root@room9pc01 ~]# chmod 777 /content
10.[root@room9pc01 ~]# echo 11 > /content/index.html
步骤二:配置客户端
1.[root@docker1 oo]# yum -y install nfs-utils
2.[root@docker1 oo]# systemctl restart nfs-server.service
3.[root@docker1 oo]# showmount -e 192.168.1.254
4.Export list for 192.168.1.254:
5./content
6.[root@docker1 ~]# mkdir /mnt/qq
7.[root@docker1 ~]# mount -t nfs 192.168.1.254:/content /mnt/qq
8.[root@docker1 ~]# ls /mnt/qq
9.index.html
10.[root@docker1 ~]# cat /mnt/qq/index.html
11.11
12.[root@docker1 ~]# docker run -d -p 80:80 -v /mnt/qq:/var/www/html -it myos:http
13.224248f0df5d795457c43c2a7dad0b7e5ec86abdc3f31d577e72f7929f020e01
14.[root@docker1 ~]# curl 192.168.1.10
15.11
16.[root@docker2 ~]# yum -y install nfs-utils
17.[root@docker2 ~]# showmount -e 192.168.1.254
18.Export list for 192.168.1.254:
19./content
20.[root@docker2 ~]# mkdir /mnt/qq
21.[root@docker2 ~]# mount -t nfs 192.168.1.254:/content /mnt/qq
22.[root@docker2 ~]# docker run -d -p 80:80 -v /mnt/qq:/var/www/html -it 192.168.1.10:5000/myos:http
23.00346dabec2c7a12958da4b7fee6551020249cdcb111ad6a1058352d2838742a
24.[root@docker2 ~]# curl 192.168.1.20
25.11
26.[root@docker1 ~]# touch /mnt/qq/a.sh
27.[root@docker1 ~]# echo 22 > /mnt/qq/index.html
28.[root@docker2 ~]#ls /mnt/qq/
29.a.sh index.html
30.[root@docker2 ~]# cat /mnt/qq/index.html
31.22
八、创建自定义网桥
4.1 问题
本案例要求:
创建网桥设备docker01
设定网段为172.30.0.0/16
启动nginx容器,nginx容器桥接docker01设备
映射真实机8080端口与容器的80端口
4.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:新建Docker网络模型
1)新建docker1网络模型
1.[root@docker1 ~]# docker network create --subnet=172.30.0.0/16 docker01
2.c9cf26f911ef2dccb1fd1f670a6c51491e72b49133246f6428dd732c44109462
3.[root@docker1 ~]# docker network list
4.NETWORK ID NAME DRIVER SCOPE
5.bc189673f959 bridge bridge local
6.6622752788ea docker01 bridge local
7.53bf43bdd584 host host local
8.ac52d3151ba8 none null local
9.[root@docker1 ~]# ip a s
10.[root@docker1 ~]# docker network inspect docker01
11.[
- {
- "Name": "docker01",
- "Id": "c9cf26f911ef2dccb1fd1f670a6c51491e72b49133246f6428dd732c44109462",
- "Scope": "local",
- "Driver": "bridge",
- "EnableIPv6": false,
- "IPAM": {
- "Driver": "default",
- "Options": {},
- "Config": [
- {
- "Subnet": "172.30.0.0/16"
- }
- ]
- },
- "Internal": false,
- "Containers": {},
- "Options": {},
- "Labels": {}
- }
32.]
2)使用自定义网桥启动容器
1.[root@docker1 ~]# docker run --network=docker01 -id nginx
3)端口映射
1.[root@docker1 ~]# docker run -p 8080:80 -id nginx
2.e523b386f9d6194e53d0a5b6b8f5ab4984d062896bab10639e41aef657cb2a53
3.[root@docker1 ~]# curl 192.168.1.10:8080
步骤二:扩展实验
1)新建一个网络模型docker02 - [root@docker1 ~]# docker network create --driver bridge docker02
2.//新建一个 名为docker02的网络模型
3.5496835bd3f53ac220ce3d8be71ce6afc919674711ab3f94e6263b9492c7d2cc
4.[root@docker1 ~]# ifconfig
5.//但是在用ifconfig命令查看的时候,显示的名字并不是docker02,而是br-5496835bd3f5
6.br-5496835bd3f5: flags=4099mtu 1500 - inet 172.18.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
- ether 02:42:89:6a:a2:72 txqueuelen 0 (Ethernet)
- RX packets 8 bytes 496 (496.0 B)
- RX errors 0 dropped 0 overruns 0 frame 0
- TX packets 8 bytes 496 (496.0 B)
- TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-
14.[root@docker1 ~]# docker network list //查看显示docker02(查看加粗字样)
15.NETWORK ID NAME DRIVER SCOPE
16.bc189673f959 bridge bridge local
17.5496835bd3f5 docker02 bridge local
18.53bf43bdd584 host host local
19.ac52d3151ba8 none null local
2)若要解决使用ifconfig命令可以看到docker02的问题,可以执行以下几步命令 - [root@docker1 ~]# docker network list //查看docker0的NETWORK ID(加粗字样)
2.NETWORK ID NAME DRIVER SCOPE
3.bc189673f959 bridge bridge local
4.5496835bd3f5 docker02 bridge local
5.53bf43bdd584 host host local
6.ac52d3151ba8 none null local
3)查看16dc92e55023的信息,如图-3所示:
1.[root@docker2 ~]# docker network inspect bc189673f959
图-3
4)查看图片的倒数第六行有"com.docker.network.bridge.name": "docker0"字样
5)把刚刚创建的docker02网桥删掉
1.[root@docker1 ~]# docker network rm docker02 //删除docker02
2.docker02
3.[root@docker1 ~]# docker network create \
4.docker02 -o com.docker.network.bridge.name=docker02
5.//创建docker02网桥
6.648bd5da03606d5a1a395c098662b5f820b9400c6878e2582a7ce754c8c05a3a
7.[root@docker1 ~]# ifconfig //ifconfig查看有docker02
8.docker02: flags=4099
- inet 172.18.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
- ether 02:42:94:27:a0:43 txqueuelen 0 (Ethernet)
- RX packets 0 bytes 0 (0.0 B)
- RX errors 0 dropped 0 overruns 0 frame 0
- TX packets 0 bytes 0 (0.0 B)
- TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
6)若想在创建docker03的时候自定义网段(之前已经创建过docker01和02,这里用docker03),执行以下命令
1.[root@docker1 ~]# docker network create docker03 --subnet=172.30.0.0/16 -o com.docker.network.bridge.name=docker03
2.f003aa1c0fa20c81e4f73c12dcc79262f1f1d67589d7440175ea01dc0be4d03c
3.[root@docker1 ~]# ifconfig //ifconfig查看,显示的是自己定义的网段
4.docker03: flags=4099mtu 1500 - inet 172.30.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
- ether 02:42:27:9b:95:b3 txqueuelen 0 (Ethernet)
- RX packets 0 bytes 0 (0.0 B)
- RX errors 0 dropped 0 overruns 0 frame 0
- TX packets 0 bytes 0 (0.0 B)
- TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0