@zhangyy
2021-07-07T07:36:26.000000Z
字数 13947
阅读 927
docker的部分
- 一: docker 的介绍
- 二: docker 的安装
- 三: 镜像的管理
Docker是一个开源的应用容器引擎,使用Go语言开发,基于Linux内核的cgroup,namespace,Union FS等技术,对应用进程进行封装隔离,并且独立于宿主机与其他进程,这种运行时封装的状态称为容器。Docker早起版本实现是基于LXC,并进一步对其封装,包括文件系统、网络互联、镜像管理等方面,极大简化了容器管理。从0.7版本以后开始去除LXC,转为自行研发的libcontainer,从1.11版本开始,进一步演进为使用runC和containerd。Docker理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意Linux发行版Docker引擎上。使用沙箱机制运行程序,程序之间相互隔离。

Containerd:是一个简单的守护进程,使用runC管理容器。向Docker Engine提供接口。Shim:只负责管理一个容器。runC:是一个轻量级的工具,只用来运行容器。

1. Namespaces命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。2. CGroups控制组,Linux内核提供的一种限制进程资源的机制;例如CPU、内存等资源。3. UnionFS联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层的模型。

以 KVM 举例,与 Docker 对比启动时间Docker秒级启动,KVM分钟级启动。轻量级容器镜像大小通常以M为单位,虚拟机以G为单位。容器资源占用小,要比虚拟机部署更快速。性能容器共享宿主机内核,系统级虚拟化,占用资源少,没有Hypervisor层开销,容器性能基本接近物理机;虚拟机需要Hypervisor层支持,虚拟化一些设备,具有完整的GuestOS,虚拟化开销大,因而降低性能,没有容器性能好。安全性由于共享宿主机内核,只是进程级隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一定安全隐患。使用 要求KVM基于硬件的完全虚拟化,需要硬件CPU虚拟化技术支持;容器共享宿主机内核,可运行在主流的Linux发行版,不用考虑CPU是否支持虚拟化技术。
场景一:节省项目环境部署时间1. 单项目打包2. 整套项目打包3. 新开源技术试用场景二:环境一致性场景三:持续集成场景四:微服务场景五:弹性伸缩参看: http://blog.51cto.com/lizhenliang/1978081
CentOS7# 安装依赖包yum install -y yum-utils device-mapper-persistent-data lvm2# 添加Docker软件包源yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 更新yum包索引yum makecache fast# 安装Docker CEyum install docker-ce -y# 启动systemctl start docker# 卸载yum remove docker-cerm -rf /var/lib/docker官方安装文档:https://docs.docker.com/engine/installation/linux/docker-ce/centos/#docker-ee-customers


linux 修改时区的方法cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtimedate -s "2018-01-27 14:17:00"
Ubuntu14.06/16.04# 安装证书sudo apt-get install \apt-transport-https \ca-certificates \curl \software-properties-common# 添加Docker源的KEYcurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -# 添加Docker软件包源sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu \$(lsb_release -cs) \stable"# 更新apt包索引sudo apt-get update# 安装sudo apt-get install docker-ce# 卸载sudo apt-get purge docker-cesudo rm -rf /var/lib/docker
什么是镜像?简单说,Docker镜像是一个不包含Linux内核而又精简的Linux操作系统。---镜像是什么?• 一个分层存储的文件• 一个软件的环境• 一个镜像可以创建N个容器• 一种标准化的交付• 一个不包含Linux内核而又精简的Linux操作系统镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME> 查看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/\<storage-driver\>中。镜像从哪里来?Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com/explore配置镜像加速器:https://www.daocloud.io/mirrorcurl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io---镜像从哪里来?Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。https://hub.docker.com/explore默认是国外的源,下载会慢,建议配置国内镜像仓库:# vi /etc/docker/daemon.json{"registry-mirrors": [ "https://registry.docker-cn.com"]}----重启一下:systemctl restart docker

镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME> 查看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/<storage-driver>中。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

如图,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,会先从镜像里要写的文件复制到容器自己的文件系统中(读写层)。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。若想持久化这些改动,可以通过docker commit 将容器保存成一个新镜像。



docker image pull httpd ## 拉取一个镜像

去这里 下载:https://download.openvz.org/template/precreated/cat centos-6-x86_64-minimal.tar.gz |docker import - centos:6.0 ## 创建镜像cat centos-7-x86_64-minimal.tar.gz |docker import - centos:7.0cat ubuntu-16.04-x86_64.tar.gz |docker import - ubuntu:16.04

docker image ls ## 列出所有镜像

docker image history httpd 查看镜像的分层历史

docker image inspect nginx 查看 一个镜像的具体信息

docker image pull nginx:1.11 # 下载一个镜像

保存一个镜像:docker image save nginx:1.11 > nginx1.11.tar.gz

删除一个一个镜像docker image rm nginx:1.11

导入一个镜像docker image load < nginx1.11.tar.gz

导出正在容器 的文件系统docker export f376547bcb01 > http.tar.gz

导入容器docker import http.tar.gz http:v2


创建一个容器docker container run -ti http:v2 /bin/bash ## 创建一个容器,退出就关闭了docker container start 9bfd4

进入一个容器docker container exec -ti 9bfd4 /bin/bash

容器与外面端口的映射docker container run -tid -p 8080:80 nginx:1.11 /bin/bashdocker container exec -ti c4a659 /bin/bashservice nginx start




创建一个一直在运行的服务docker container run -tid --name nginx01 --restart=always nginx:1.11

创建容器,限制容器的cpudocker container run --help |grep cpu

docker container run -tid --memory 512M --cpus 1 --name nginx02 nginx:1.11查看使用的量docker container stats


查看有哪些容器docker container ls

查看容器的详细信息docker container inspect c44023d07aab

附加到容器docker container attach c44 ### 如果 容器正在运行程序则进不了容器docker container exec c44 /bin/bash ### 进入的容器必须是已经启动的容器

提交一个容器到镜像 仓库docker container commit c44023d07aab nginx:test1

向容器中复制东西docker container cp anaconda-ks.cfg nginx02:/rootdocker container exec nginx02 ls /root


docker container logs nginx02 ### 查看容器的日志
docker container port c4a6593972f6 ## 查看容器的映射端口

Docker提供三种不同的方式将数据从宿主机挂载到容器中:volumes,bind mounts和tmpfs。volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。bind mounts:可以存储在宿主机系统的任意位置。tmpfs:挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统。

cd /var/lib/docker/volumesdocker volume create nginx-voldocker volume lsdocker run -d -it --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx ### 创建容器并使用建好的volume 卷处理docker volume create nginxz-voldocker volume lsdocker run -tid --name=nginxz --mount src=nginxz-vol,dst=/usr/local nginxz:1.11docker volume create httpd-voldocker volume lsdocker run -tid --name=httpd-test --mount src=httpd-vol,dst=/usr/local httpd如果一个数据卷可以挂载在不同的容器当中,就可以实现端口的负载了







进入这个容器docker container exec -ti nginx-test bashcd /usr/share/nginx/html/touch 1.txt退出容器cd /var/lib/docker/volume/nginx-vol/_data/ls -ld *


删除所有容器docker rm -f $(docker ps -q -a)

用卷创建 一个容器:# mkdir -p /app/www/html# docker run -d -it --name=nginx-test --mount type=bind,src=/app/www/html,dst=/usr/share/nginx/html nginx# docker run -d -it --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx验证绑定:# docker inspect nginx-test清理:# docker container stop nginx-test# docker container rm nginx-test注意:1. 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。2. 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏

Docker报错 WARNING: IPv4 forwarding is disabled. Networking will not work.# vim /usr/lib/sysctl.d/00-system.conf加上:net.ipv4.ip_forward=1重启网卡:service network restart
0 、 宿主机安装mysql8.0rpm -e mariadb-devel mariadb-libs mariadb --nodepsyum install -y perl-JSONrm -rf mysql-community-server-minimal-8.0.11-1.el7.x86_64.rpmrpm -ivh mysql-community-*1 、自定义网络docker network create lnmp2 、创建 Mysql 数据库容器docker run -itd \--name lnmp_mysql \--net lnmp \-p 3306:3306 \--mount src=mysql-vol,dst=/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=123456 \mysql --character-set-server=utf83 、创建 所需 数据库docker exec lnmp_mysql sh \-c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"create database wp"'4 、创建 PHP 环境容器docker run -itd \--name lnmp_web \--net lnmp \-p 88:80 \--mount type=bind,src=/app/wwwroot,dst=/var/www/html richarvey/nginx-php-fpm 5 、 以 wordpress 博客为例测试wget https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gztar zxf wordpress-4.7.4-zh_CN.tar.gz -C /app/wwwroot容器的访问:iptables -I INPUT -s 0.0.0.0 -j ACCEPTiptables -I INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT# 浏览器测试访问http://IP:88/wordpress/

数据的主机填写lnmp_mysql是docker的构建的mysql的名字

Docker 支持 5 种 网络模式1. bridge默认网络,Docker启动后默认创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。2. host容器不会获得一个独立的network namespace,而是与宿主机共用一个。3. none获取独立的network namespace,但不为容器进行任何网络配置。4. container与指定的容器使用同一个network namespace,网卡配置也都是相同的。5. 自定义自定义网桥,默认与bridge网络一样。
docker 的 bridge 网络Docker 容器默认使用 bridge 模式的网络。其特点如下:使用一个 linux bridge,默认为 docker0使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与veth pair的 IP地址不在同一个网段内Docker采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口port 进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 portNAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过NAT建立通信


host 模式docker run -tid --name centos_host1_test --net host centos_test会与宿主机公用一个网络

none 模式docker run -tid --name centos1_none --net none centos_test这个模式下面是单独的网络,没有IP 地址

Linux IP 信息包过滤原理:Docker主要通过netfilter/iptables实现网络通信。iptables由netfilter和iptables组成,netfilter组件是Linux内核集成的信息包过滤系统,它维护一个信息包过滤表,这个表用于控制信息包过滤处理的规则集。而iptables只是一个在用户空间的工具,用于增删改查这个过滤表的规则。

容器 访问外部# iptables -t nat -nLChain POSTROUTING (policy ACCEPT)target prot opt source destinationMASQUERADE all -- 172.17.0.0/16 0.0.0.0/0外部 访问容器# iptables -t nat -nLChain DOCKER (2 references)target prot opt source destinationDNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:88 to:172.18.0.2:80创建一个容器:docker run -ti --name centos_test /bin/bash


临时网络# 网桥名称br_name=br0# 添加网桥brctl addbr $br_name# 给网桥设置IPip addr add 192.168.0.211/24 dev $br_name# 删除已存在的eth0网卡配置ip addr del 192.168.0.211/24 dev eth0# 激活网桥ip link set $br_name up# 添加eth0到网桥brctl addif $br_name eth0# 添加路由ip route add default via 192.168.0.1 dev br0-----还需要在Docker启动时桥接这个网桥:# vi /usr/lib/systemd/system/docker.serviceExecStart=/usr/bin/dockerd -b=br0# systemctl restart docker


永久生效:# vi /etc/sysconfig/network-scripts/ifcfg-eth0DEVICE=eth0TYPE=EthernetONBOOT=yesBRIDGE=br0# vi /etc/sysconfig/network-scripts/ifcfg-br0DEVICE=br0TYPE=BridgeONBOOT=yesBOOTPROTO=staticIPADDR=192.168.0.211NETMASK=255.255.255.0GATEWAY=192.168.0.1DNS1=114.114.114.114
配置 固定 IPC_ID=$(docker run -itd --net=none ubuntu)C_PID=$(docker inspect -f '{{.State.Pid}}' $C_ID)# 创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取mkdir -p /var/run/netnsln -s /proc/$C_PID/ns/net /var/run/netns/$C_PID# 添加虚拟网卡veth+容器PID,类型是veth pair,名称是vp+容器PIDip link add veth$C_PID type veth peer name vp$C_PID# 添加虚拟网卡到br0网桥brctl addif br0 veth$C_PID# 激活虚拟网卡ip link set veth$C_PID up# 设置容器网络信息IP='192.168.0.123/24'GW='192.168.0.1'# 给进程配置一个network namespaceip link set vp$C_PID netns $C_PID# 在容器进程里面设置网卡信息ip netns exec $C_PID ip link set dev vp$C_PID name eth0ip netns exec $C_PID ip link set eth0 upip netns exec $C_PID ip addr add $IP dev eth0ip netns exec $C_PID ip route add default via 192.168.1.1这种方法一般不采用:
采取的方法:pipework 工具配置容器固定 IPgit clone https://github.com/jpetazzo/pipework.gitcp pipework/pipework /usr/local/bin/docker run -tid --name centos1_none --net none centos_testpipework br0 centos1_none 172.17.100.11/24@172.17.100.2进入这个容器docker exec -ti e95dff5 bash这个只是临时配置的,重启容器就丢了,docker 不建议这样做。




Usage: docker image build [OPTIONS] PATH | URL | -Options:-t, --tag list # 镜像名称-f, --file string # 指定Dockerfile文件位置示例:docker build .docker build -t shykes/myapp .docker build -t shykes/myapp -f /path/Dockerfile /path
FROM centos:7MAINTAINER www.aliangedu.comRUN yum install -y gcc gcc-c++ make openssl-devel pcre-develADD nginx-1.12.1.tar.gz /tmpRUN cd /tmp/nginx-1.12.1 && \./configure --prefix=/usr/local/nginx && \make -j 2 && \make installRUN rm -rf /tmp/nginx-1.12.1* && yum clean allCOPY nginx.conf /usr/local/nginx/confWORKDIR /usr/local/nginxEXPOSE 80CMD ["./sbin/nginx", "-g", "daemon off;"]----执行构建cd nginx/docker build -t nginx:v1 -f Dockerfile .
FROM centos:7MAINTAINER www.aliangedu.comRUN yum install -y gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-develADD php-5.6.31.tar.gz /tmp/RUN cd /tmp/php-5.6.31 && \./configure --prefix=/usr/local/php \--with-config-file-path=/usr/local/php/etc \--with-mysql --with-mysqli \--with-openssl --with-zlib --with-curl --with-gd \--with-jpeg-dir --with-png-dir --with-iconv \--enable-fpm --enable-zip --enable-mbstring && \make -j 4 && \make install && \cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \sed -i "s/127.0.0.1/0.0.0.0/" /usr/local/php/etc/php-fpm.conf && \sed -i "21a \daemonize = no" /usr/local/php/etc/php-fpm.confCOPY php.ini /usr/local/php/etcRUN rm -rf /tmp/php-5.6.31* && yum clean allWORKDIR /usr/local/phpEXPOSE 9000CMD ["./sbin/php-fpm", "-c", "/usr/local/php/etc/php-fpm.conf"]-----执行构建命令cd /root/php/docker build -t php:v1 -f Dockerfile .

1 、自定义网络docker network create lnmp2 2 、创建 PHP 容器docker run -itd \--name lnmp_php \--net lnmp \--mount type=bind,src=/app/wwwroot/,dst=/usr/local/nginx/html \php:v13 3 、创建 Nginx 容器mkdir -p /app/wwwroot/docker run -itd \--name lnmp_nginx \-p 888:80 \--net lnmp \--mount type=bind,src=/app/wwwroot/,dst=/usr/local/nginx/html \nginx:v14 4 、创建 MySQL 容器docker run -itd \--name lnmp_mysql \--net lnmp \-p 3306:3306 \--mount src=mysql-vol,dst=/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=123456 \mysql --character-set-server=utf8


FROM centos:7MAINTAINER www.aliangedu.comADD jdk-8u45-linux-x64.tar.gz /usr/localENV JAVA_HOME /usr/local/jdk1.8.0_45ADD apache-tomcat-8.0.46.tar.gz /usr/localCOPY server.xml /usr/local/apache-tomcat-8.0.46/confRUN rm -f /usr/local/*.tar.gzWORKDIR /usr/local/apache-tomcat-8.0.46EXPOSE 8080ENTRYPOINT ["./bin/catalina.sh", "run"]-------------cd /root/tomcat/docker build -t tomcat:v1 -f Dockerfile .------------开启容器:mkdir -p /app/webapps/docker run -itd \--name=tomcat \-p 8080:8080 \--mount type=bind,src=/app/webapps/,dst=/usr/local/apache-tomcat-8.0.46/webapps \tomcat:v1cd /app/webapps/mkdir ROOTcd ROOTecho "hello world" >> index.html


Docker Hub作为Docker默认官方公共镜像;如果想自己搭建私有镜像仓库,官方也提供registry镜像,使得搭建私有仓库非常简单。下载 registry 镜像并启动# docker pull registry# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry测试 ,查看镜像仓库中所有镜像# curl http://172.17.100.11:5000/v2/_catalog{"repositories":[]}


搭建私有镜像仓库1 1 、配置 私有仓库可信任# vi /etc/docker/daemon.json{"insecure-registries":["172.17.100.11:5000"]}# systemctl restart docker2 、打标签# docker tag centos7.0:v1 172.17.100.11:5000/centos7.0:v13 、上 传# docker push 172.17.100.11:5000/centos7.04 、下载# docker pull 172.17.100.11:5000/centos7.05 、列出 镜像标签# curl http://172.17.100.11:5000/v2/centos7.0/tags/list私有镜像仓库管




1 、注册账号https://hub.docker.com2 、登录 Docker Hub# docker login或# docker login --username=zhangyy --password=1234563 、镜像打标签# docker tag wordpress:v1 zhangyy/wordpress:v14 、上传# docker push zhangyy/wordpress:v1搜索测试:# docker search zhangyy5 、下载# docker pull zhangyy/wordpress:v1
Portainer是一个开源、轻量级Docker管理用户界面,基于Docker API,可管理Docker主机或Swarm集群,支持最新版Docker和Swarm模式。1 1 、创建卷# docker volume create portainer_data2 2 、创建P P ortainer 容器# docker run -d \-p 9000:9000 \-v /var/run/docker.sock:/var/run/docker.sock \-v portainer_data:/data \portainer/portainer



创建一个网络docker create network monitorInfluxdbdocker run -d \--name influxdb \--net monitor \-p 8083:8083 \-p 8086:8086 \tutum/influxdbcAdvisordocker run -d \--name=cadvisor \--net monitor \-p 8081:8080 \--mount type=bind,src=/,dst=/rootfs,ro \--mount type=bind,src=/var/run,dst=/var/run \--mount type=bind,src=/sys,dst=/sys,ro \--mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker,ro \google/cadvisor \-storage_driver=influxdb \-storage_driver_db=cadvisor \-storage_driver_host=influxdb:8086Grafanadocker run -d \--name grafana \--net monitor \-p 3000:3000 \grafana/grafana


