Docker系列课程之一:基础篇
in 技术 with 0 comment 阅读:33次
Docker系列课程之一:基础篇
in 技术 with 0 comment 阅读:33次

一、什么是Docker及其体系架构 1、什么是Docker?体系架构 ()Docker是一个容器的引擎(虚拟机) ()让开发人员可以打包自己的应用程序(依赖:包、资源) ()虚拟化 ()组成: (1)Docker Client客户端:Docker命令 (2)Docker Daemon守护进程 (3)Docker Image镜像模板:分层结构 (4)Docker Container容器

2、安装和配置Docker实验环境:Centos
	(*)关闭防火墙
			systemctl stop firewalld.service
			systemctl disable firewalld.service  永久关闭防火墙

	(*)使用在线安装的方式
			yum install docker
			启动Docker服务
			systemctl start docker
			systemctl enable docker 开机自启
			查看Docker版本
			docker version

二、Docker的镜像:image(模板---->创建容器) 什么是Docker镜像? (1)镜像是一个模板 (2)镜像采用分层的文件系统 (3)镜像是容器运行的基石 (4)可以从镜像仓库中进行拉取(公有、私有harbor)

1、使用和访问官方的Docker的镜像仓库(hub)  https://hub.docker.com
	docker search **** 搜索镜像模板
	docker pull *** 拉取镜像(下载本地)
	docker run 命令创建容器
	
	举例1:拉取MySQL的镜像,创建一个容器
		docker search mysql
		docker pull mysql  ----> 默认:latest版本
		docker images  ----> 查看本地下载的镜像
		docker run --name my_mysql_demo -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Welcome_1 -d mysql
		说明: --name 指定容器的名称
		       -p     指定宿主机和容器之间的端口映射
			   -e     设置环境变量
			   -d     启动容器进程(后台,返回container id)
			   mysql  镜像的名称
		进入容器:
		docker exec -it CONTAINER_ID /bin/bash
		docker exec -it eadee3a87f29 /bin/bash
		
	举例2:拉取Tomcat的镜像,创建一个容器
		docker search tomcat
		docker pull tomcat
		docker images
		docker run --name my_tomcat_demo -d -p 8080:8080 tomcat


2、配置和使用阿里云提供的Docker镜像加速器
	mkdir -p /etc/docker
	tee /etc/docker/daemon.json <<-'EOF'
	{
	  "registry-mirrors": ["https://giwrd70q.mirror.aliyuncs.com"]
	}
	EOF
	systemctl daemon-reload
	systemctl restart docker	
	
	地址
	Registry Mirrors:
	 https://giwrd70q.mirror.aliyuncs.com
	

3、管理镜像(Docker命令)
	docker search [NAME] 在镜像仓库中搜索镜像
	docker pull [NAME] 拉取镜像(latest)
	docker push [NAME] 上传到镜像仓库中
	docker images 列出本地的所有镜像(基本信息)
	docker images m*  支持通配符
	docker inspect [NAME]/[CONTAINER_ID] 列出镜像(容器)的详细信息
	docker rmi [NAME] 删除镜像
	                  参数:-f 强制删除
					  如果有多个镜像,采用空格进行分隔
	docker run 使用镜像创建容器


4、构建Docker镜像(上传到docker hub)
	(1)使用docker commit
		举例:1、使用Docker部署一个Tomcat的容器
					docker pull tomcat
					docker run -d --name tomcat_web_app -p 8080:8080 tomcat
		
		      2、在Tomcat容器中部署一个简单的Web应用(修改容器)
					docker exec -it 6490798df72b /bin/bash
					
					cd webapps
					mkdir mydemo
					cd mydemo
					echo '

Hello Tomcat

' > a.html 3、将容器保存docker commit -----> 本地 docker commit 6490798df72b tomcat_web_app_local 将容器保存docker commit -----> 镜像仓库中 登录 docker login docker commit 6490798df72b collenzhao/tomcat_web_app_remote 4、使用docker push命令上传的镜像 docker push collenzhao/tomcat_web_app_remote (2)使用Dockerfile(命令:docker build) (1)创建一个Dockerfile(-f参数指定文件名称) 基于Nginx镜像,部署一个简单的Web App应用 FROM nginx RUN echo '

This is a Demo WebApp

' > /usr/share/nginx/html/index.html (2)使用docker build命令,生成镜像 docker build -t nginx:mylatest . (3)创建一个容器 docker run -d -p 7788:80 nginx:mylatest 5、Dockerfile使用(综合例子) (1)Docker镜像、Docker容器、Dockerfile三者的关系 参考PPT (2)Dockerfile的基本概念 (*)Docker镜像是一个特殊的文件系统 (*)Dockerfile基于文本的配置文件,包含一条条的指令。每一条指令构建分层文件系统中的一层 (*)docker build构建image镜像 (3)Dockerfile文件格式:4部分 (*)基础镜像信息 (*)维护者的信息 (*)镜像操作命令 (*)容器启动执行的命令 (4)综合的例子: (*)从一个基本的centos基础镜像开始 (*)安装JDK和Tomcat (*)在tomcat中部署一个Web App应用 (*)启动容器,访问Web App的应用 创建Dockerfile FROM centos MAINTAINER zhaoqiang zhaoqiang@example.com RUN mkdir /root/training RUN mkdir /root/tools COPY jdk-8u144-linux-x64.tar.gz /root/tools RUN tar zxvf /root/tools/jdk-8u144-linux-x64.tar.gz -C /root/training/ ENV JAVA_HOME /root/training/jdk1.8.0_144 ENV PATH $JAVA_HOME/bin:$PATH ADD http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.35/bin/apache-tomcat-8.5.35.tar.gz /root/tools RUN tar zxvf /root/tools/apache-tomcat-8.5.35.tar.gz -C /root/training/ COPY MyDemoWeb.war /root/training/apache-tomcat-8.5.35/webapps ENTRYPOINT ["/root/training/apache-tomcat-8.5.35/bin/catalina.sh","run"] 命令:FROM 指定基础镜像 MAINTAINER 维护者的信息 RUN 执行一条命令 COPY 从宿主机上拷贝一个文件到镜像模板中 ENV 设置环境变量 ADD 添加一个URL的地址(下载文件) ENTRYPOINT 启动容器的时候,执行命令 编译的命令:docker build -t mywebapp . 启动容器: docker run -d -p 8080:8080 mywebapp

三、Docker的容器(container) 1、容器的基本操作:创建容器、停止容器、进入容器、删除容器 导入和导出容器(迁移)、查看容器等等

	(1)创建容器
			命令:run、create、start
			区别:run = create + start
	
			例子:docker create --name mycontainer1 centos
				无法通过docker ps命令来查看容器,因为容器没有运行
				  docker start [container id]
	(2)停止容器 docker stop
	(3)进入容器 docker exec -it 47ceba4e6e66 /bin/bash
					参数  -i 保持标准输入打开
					      -t 分配一个伪终端
						  
	(4)删除容器: docker rm 47ceba4e6e66
	(5)导入和导出容器(迁移)
		注意:不管容器处于什么状态,都可以使用export导出操作
			docker export 
				docker export -o mywebapp.tar 47ceba4e6e66
				
			docker import 把导入的tar包变成一个镜像
				docker import mywebapp.tar mywebapp_imported


2、容器的日志
	(1)Docker引擎的日志:一般来说,由操作系统来维护
			Centos 7:journalctl -u docker
	
	(2)容器的日志:命令 docker logs [CONTAINER_ID]
			命令:docker logs -f -t --since="2018-12-01" --tail=20 47ceba4e6e66
				-f 查看实时日志,类似 tail -f
				-t 查看日志产生的日期
				--since 指定了输入日志的开始期(只输出指定日期后产生的日志)
				--tail   查看最后的20条日志

	
3、管理容器的资源
	(1)基础知识:Linux Control Groups
		(*)什么是Linux Control Groups?
				简单来说:以一组进程为目标进行系统资源的分配和控制。
				
		(*)功能
				限制资源的使用
				优先级的控制
				审计
				控制功能:挂起进程、恢复执行进程
				
		(*)查看Linux的内核中,是否启用了cgroup的功能
				uname -r
				cat /boot/config-3.10.0-693.el7.x86_64 |grep CGROUP
				
		(*)Demo1:限制进程(应用程序)对CPU的使用率
			开发一个c程序:死循环
			int main(void){
				int i=0;
				for(;;) i++;
				return 0;
			}
			
			使用gcc进行编译: yum install gcc
			gcc -o hello hello.c
			
			对应用程序的CPU的使用率进行限制:20%
			cd /sys/fs/cgroup/cpu
			mkdir my001
			cd my001
			
			查看cat cpu.cfs_quota_us
			-1  表示:没有任何的限制
			
			echo 20000 > cpu.cfs_quota_us
			把hello的进程号 ---> tasks中
			echo 6565 > tasks
			
			再启动一个hello程序
			两个hello程序总的CPU的使用:20%
		
		(*)Demo2:限制进程(应用程序)对内存的使用
			cd /sys/fs/cgroup/memory/my001 如果没有这个目录,创建这个目录
			查看cat memory.limit_in_bytes
			9223372036854771712  可以没有任何限制
			
			规定hello的应用程序最多只能使用64K的内存
			echo 64k > memory.limit_in_bytes
			
			把hello的进程号写到tasks
			echo 6633 > tasks
			
			如果6633(hello的应用程序)的内存使用超过64K,自动被kill
		
		(*)Demo3:限制进程(应用程序)对I/O使用
				安装工具:iotop 类似top命令 监视磁盘的IO的情况
				
			命令:dd if=/dev/sda of=/dev/null 不断访问磁盘
			使用iotop监视磁盘的IO的情况
			
			cd /sys/fs/cgroup/blkio/my001  如果没有这个目录,创建这个目录
			显示对磁盘的IO的访问:10M之内
			
			echo '8:0 10485760' > blkio.throttle.read_bps_device
			把进程号输出到tasks中(生效)
			echo 6671 > tasks
			
	(2)Docker对容器使用CPU的使用率:是相对权重
			准备实验的环境 Dockerfile
				FROM centos:latest
				RUN yum install -y epel-release && yum install -y stress
				ENTRYPOINT ["stress"]
			docker build -t centos001 .
			
			启动两个容器,分配CPU使用率的不同权重(相对)
			docker run -it centos001 --cpu 4     ----> 默认CPU使用率的权重:1024
			docker run -it -c 512 centos001 --cpu 4  ----->CPU使用率的权重:512
			
			通过命令:docker stats
				CONTAINER           CPU %              
				ecd45c19e72d        32.50%             
				3562d2c5a40f        66.21%             
	
	(3)Docker对容器使用的内存管理和限制
		 默认:一个容器可以使用宿主机上所有的内存
		 使用命令:docker run -m开关:使用内存的大小
		 
		 docker run -it -m 128m centos001 --cpu 4
		 -m 指定容器的使用内存的上限
		 
		 通过docker stats查看
		CONTAINER           CPU %               MEM USAGE / LIMIT  
		1cb50eaff3f4        97.36%              192 KiB / 128 MiB  
			
	(4)Docker对容器使用I/O的管理和限制
			很多参数:参考PPT
			
		Demo1: --blkio-weight 参数(测试的时候,效果不是很理想)
				docker run -it --blkio-weight 100 centos /bin/bash
				docker run -it --blkio-weight 1000 centos /bin/bash
				
				在两个容器中,同时执行dd命令
				dd if=/dev/zero of=test.out bs=1M count=3000
				
		Demo2:--device-read-bps和--device-write-bps
				限制容器读入和写出的速率:1M(每秒)
				
				写入速率的上限:1M
				docker run -it --device-write-bps /dev/sda:1mb centos /bin/bash
				
				在容器内部:dd if=/dev/zero of=test.out bs=1M count=20 oflag=direct
				            oflag=direct表示:读写数据采用直接IO

				读取数据速率的上限:1M
				docker run -it --device-read-bps /dev/sda:1mb centos /bin/bash
				
		Demo3: --device-write-iops和--device-read-iops
				以写数据为例:容器write iops 是5/秒(次数)
				
				docker run -it --device-write-iops /dev/sda:5 centos /bin/bash
				
				在容器内部执行: dd if=/dev/zero of=test.out bs=1M count=200 oflag=direct
				
				使用命令观察: iostat 1 (安装:yum install sysstat)
				
				也能针对读,进行限制
				docker run -it --device-read-iops /dev/sda:5 centos /bin/bash
				
	
	

四、Docker网络和容器的通信 1、Docker网络通信的基本原理 (1)Docker的网络接口是虚拟的接口 (2)虚拟的网络接口的转发的效率高 (3)宿主机的信息 docker0: flags=4163 mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:52ff:fe4b:4e4c prefixlen 64 scopeid 0x20 ether 02:42:52:4b:4e:4c txqueuelen 0 (Ethernet) RX packets 8 bytes 536 (536.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

		vethd1b406d: flags=4163  mtu 1500
				inet6 fe80::78da:cfff:feef:44b5  prefixlen 64  scopeid 0x20
				ether 7a:da:cf:ef:44:b5  txqueuelen 0  (Ethernet)
				RX packets 8  bytes 648 (648.0 B)
				RX errors 0  dropped 0  overruns 0  frame 0
				TX packets 16  bytes 1296 (1.2 KiB)
				TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
				
	(4)到容器内部查看网卡的信息
		eth0: flags=4163  mtu 1500
				inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
				inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20
				ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
				RX packets 1819  bytes 8445579 (8.0 MiB)
				RX errors 0  dropped 0  overruns 0  frame 0
				TX packets 1687  bytes 95886 (93.6 KiB)
				TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
	
	(5)Docker创建容器的时候,会执行下面的操作
		(*)创建一对的虚拟的网络接口,一个放在本地的主机和新容器的各自的命名空间中
		(*)本地主机一端的虚拟的接口连接到默认的docker0的网桥上,取名:veth****
		(*)容器一端:把虚拟的网络接口放到新容器中,改名:eth0
		(*)从网桥(docker0)获取一个空闲的IP地址,分配给容器的eth0的网卡

2、Docker的网络模式:
	四种不同的网络模式:host、container、bridge(默认)、none
	命令:docker network ls
	NETWORK ID          NAME                DRIVER              SCOPE
	845b88ede2ca        bridge              bridge              local
	74a262ef9181        host                host                local
	6bcd1c1ff2ea        none                null                local
	
	镜像:busybox集成了一百多个Linux的工具箱
	
	(*)host:容器不会虚拟出自己的网卡,直接使用宿主机的IP和端口
			docker run -it --network=host busybox /bin/sh
			信息:
			docker0   Link encap:Ethernet  HWaddr 02:42:52:4B:4E:4C  
					  inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
					  inet6 addr: fe80::42:52ff:fe4b:4e4c/64 Scope:Link
					  UP BROADCAST MULTICAST  MTU:1500  Metric:1
					  RX packets:1692 errors:0 dropped:0 overruns:0 frame:0
					  TX packets:1812 errors:0 dropped:0 overruns:0 carrier:0
					  collisions:0 txqueuelen:0 
					  RX bytes:72456 (70.7 KiB)  TX bytes:8444973 (8.0 MiB)				
	
	(*)container:容器不会虚拟出自己的网卡,和一个指定的容器共享IP和端口
			启动两个容器:第一个 docker run -it busybox /bin/sh   ---> 使用bridge的模式
			                     信息
								eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
										  inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
						  
						  第二个 docker run -it --network=container:d8c0a1aa2673 busybox /bin/sh
						         其中:d8c0a1aa2673是另一个容器的ID
								eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
										  inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
	
	(*)bridge:默认的模式,会为每一个新创建的容器分配网络配置(IP等等)
	
	(*)none:关闭了容器的网络功能
				docker run -it --network=none busybox /bin/sh
				
				通过ifconfig,无法查看到eth0的信息


	自定义bridge的模式
		(1)创建自己的网络:bridge
		     docker network create -d bridge --ip-range=192.168.78.0/24 --gateway=192.168.78.1 --subnet=192.168.78.0/24 bridge2
			 
			 查看网络模式的详情:docker network inspect 3e7b5641cbeb
			 
		(2)创建自己的容器,使用自定义的网络模式(bridge2)
			docker run -it --network=bridge2 --ip=192.168.78.3 busybox
			docker run -it --network=bridge2 --ip=192.168.78.4 busybox

3、容器间的通信
	(1)IP通信
			docker run -it --network=bridge2 --ip=192.168.78.3 busybox
			docker run -it --network=bridge2 --ip=192.168.78.4 busybox	

			缺点:不够灵活
	
	(2)Docker DNS Server
		(*)版本:1.10以后
		(*)参数:--name
			docker run -it --network=bridge2 --name box1 busybox
			docker run -it --network=bridge2 --name box2 busybox
	
	(3)Joined容器:本质就是container网络模式
		(*)基于httpd的镜像创建容器
			docker run -it --name box3 httpd
			
		(*)使用Joined容器创建一个新的容器
		    docker run -it --network=container:box3 busybox
			
		(*)测试:在第二个容器中执行wget 127.0.0.1

4、容器访问控制
	(1)容器访问外部网络
		(*)需要宿主机的转发
			 docker run -it centos
			 sysctl net.ipv4.ip_forward ---> 是1,开启了转发功能
			                              是0,没有开启转发
										  
			 通过下面方式开启
			 sysctl -w net.ipv4.ip_forward=1
			 
			 更简单:启动docker服务的时候指定:  --ip-forward=true
	
	
	(2)外部访问容器网络:通过指定-p参数进行端口映射
			docker run -it -p 80:80 centos bash
			在宿主机上:iptables -nL查看

五、Docker的数据管理:数据的共享 1、Docker的数据卷(共享目录) ()相当于mount操作 ()是一个可供容器使用的特殊的目录 ()实现主机操作系统与容器之间进行目录的映射 ()特性 (1)数据卷可以在容器之间实现数据的共享和重用 (2)对数据卷内数据的修改会立即生效 (3)对数据卷的更新不会影响镜像 (4)数据卷会一直存在,直到没有容器使用

	(*)Demo演示:在主机和容器之间创建数据卷,实现数据共享(共享目录)
			docker run -it -v /root/mydatavolume:/root/container/mydatavolume centos /bin/bash
			
			-v 指定数据卷的目录
			
		默认:挂载的数据卷默认权限是读写(RW),也可以通过指定ro参数标识为只读
			docker run -it -v /root/mydatavolume:/root/container/mydatavolume:ro centos /bin/bash
			
	(*)新版本的docker:使用命令: docker volume 命令管理数据卷
		docker volume create ----> 也可以创建数据卷
		
	(*)问题:Permission denied
		  原因:Centos 7的安全模块selinux把权限给禁掉了
		  (1)--privileged=true 加入到docker run中
		  (2)临时关闭SeLinux: setenforce 0
	

2、Docker的数据卷容器
	(*)数据卷容器也是一个容器,目的:专门用来提供数据卷供其他的容器挂载
	(*)实现在多个容器之间数据数据的共享
	(*)Demo演示:创建数据卷容器
		(1)创建一个数据卷容器dbdatacontainer,在这个容器中创建一个数据卷挂载: /dbdata
				docker run -it -v /dbdata --name dbdatacontainer centos
	
		(2)可以在其他的容器中使用 --volumes-from来挂载dbdatacontainer容器中的数据卷
				docker run -it --volumes-from dbdatacontainer --name db1 centos
				docker run -it --volumes-from dbdatacontainer --name db2 centos
		

3、利用数据卷容器来实现数据的迁移:数据的备份和恢复
	(*)备份:使用下面的命令备份dbdatacontainer数据卷容器内的数据卷(tar包)
		docker run --volumes-from dbdatacontainer -v $(pwd):/backup --name myworker centos tar cvf /backup/backup.tar /dbdata
		
	(*)恢复:如果要将数据恢复到一个容器中
		(1)创建一个带有数据卷的容器
				docker run -it -v /dbdata --name dbdatacontainer2 centos
				
		(2)docker run -it --volumes-from dbdatacontainer2 -v $(pwd):/backup --name worker2 centos /bin/bash

六、Docker应用实战篇 1、Docker与数据库: MySQL (*)演示:在Docker容器中运行MySQL docker search mysql docker pull mysql docker run --name my_mysql_demo1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Welcome_1 -d mysql

	(*)数据库不适合运行在Docker容器中,为什么?
		(1)数据不安全
		(2)运行数据库的时候需要一些硬件环境的支持
		(3)网络的问题
		(4)Docker中打包的应用是无状态的应用

	
2、Docker与nginx
	(*)基于Ubuntu的系统,安装nginx,然后部署一个简单的web app
	(*)创建Dockerfile
	FROM ubuntu:14.04
	RUN apt-get update
	RUN apt-get install -y nginx
	RUN echo '

Hello World and Nginx

' > /usr/share/nginx/html/index.html EXPOSE 80 ENTRYPOINT tail -f /dev/null 使用docker build进行编译 docker build -f file1 -t mynginx1 . 启动容器:docker run -d -p 80:80 mynginx1 手动启动nginx服务,进入容器,执行:/usr/sbin/nginx 访问网页 3、Docker与PHP (*)需求:基于Centos,部署PHP的环境 ----> docker commit ---> 镜像 (*)步骤: (1)注意:由于Centos 7存在一个bug,建议使用Centos 6 (2)拉取Centos6 docker pull centos:6 (3)启动容器 docker run -it -p 1234:80 0cbf37812bff /bin/bash (4)安装Apache(在容器中执行) yum install httpd chkconfig httpd on service httpd start (5)在容器中安装PHP yum install php yum install php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc (6)写一个简单的php 注意:打开一些开关 (php.ini) ; short_open_tag ; Default Value: On ; Development Value: Off ; Production Value: Off 重启apache (7)docker commit ---> 镜像 docker commit 7b4c8a58438f mycentos_php 4、Docker与Python (*)基于Centos (*)通过两种不同的方式 (1)docker commit安装Python3的镜像 (2)通过dockerfile安装Python3的运行环境 参考提供的文档 5、Docker与Jupyter NootBook 参考提供的文档 6、Docker与TensorFlow 参考提供的文档 from __future__ import print_function import tensorflow as tf with tf.Session(): input1 = tf.constant([1.0, 2.0, 3.0, 4.0]) input2 = tf.constant([2.0, 3.0, 4.0, 5.0]) output = tf.add(input1, input2) result = output.eval() print("result: ", result) 7、Docker与OpenStack的关系 (后续)Docker与大数据:Hadoop、Spark等等

七、搭建Harbor私有镜像仓库 1、什么是Harbor? 2、安装和配置Harbor 3、访问私有的镜像仓库Harbor

浪浪山

Responses
您是第 1086522 位访客