如果出现无法载图的情况,请检查与github的连通性
Docker架构 Docker构成 1、docker deamon 守护进程(提供docker服务) 2、docker restful-api(http/https 发起访问) 3、client docker cli(运维使⽤docker 命令⾏进⾏docker管理)(容器/镜像/存储/⽹络)
Docker框架 1、docker host运行docker主机 2、docker client命令行控制的客户端 3、docker registry镜像仓库
docker版本: ——CE版本(社区版) ——EE版本(企业版) ——edge版-每月更新 体验版 ——stable版-稳定版
镜像相关: docker registry是存放容器镜像的仓库,用户可以进行镜像下载和访问,分为公有和私有两类registry
公有镜像仓库比如 docker hub,是docker公司为公众提供的托管registry,是世界上最大的容器镜像仓库Docker Hub quay.io,是红帽的公共托管registryRepositories · Quay
私有镜像仓库可以由企业搭建私有registry,也可以由个人搭建
Docker的安装 从官网安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 centos7.8.2003 192.168.8.150/24 gw 192.168.8.254 NAT网络,确保能连上网络即可 curl -fskSL get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo sh get-docker.sh --mirror Aliyun systemctl enable docker --now usermod -aG docker ws id wssu - ws docker run hello-world ps -ef | grep -i dockerd root 13168 0.4 1.9 1554288 75428 ? Ssl 18:40 0:57 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
从yum/apt等包管理器安装 1 2 3 4 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum -y update yum -y install docker-ce systemctl enable docker --now
基础docker操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 docker --version docker version docker info docker run httpd docker run -d docker run -p 1234:8080/tcp docker run -P docker run --name docker run -it ...... /bin/bash docker run -v 宿主机路径:容器内地址 eg:docker run -itd --name test -p 1234:8080/tcp -v /iso:/var/tftp/boot centos /bin/bash docker exec -it 886c57251999 /bin/bash exit docker start containerID docker restart containerID docker ps docker ps -a docker ps -q docker stop containerID docker stop $(docker ps -aq) docker kill containerID docker rm containerID docker rm -f containerID docker rm $(docker ps -aq) docker cp 宿主机⽂件路径 容器id :路径 docker search httpd docker pull httpd docker pull mysql:5.7 docker images docker images -a docker images -q docker tag xxxxxxxx httpd docker rmi httpd or docker image rm httpd docker rmi hello-world:latest docker rmi -f hello-world
Docker镜像
1 2 3 4 5 6 7 容器镜像封装加载 docker pull centos/httpd-24-centos7 docker run -d -p 10001:8080 --name cm01 centos/httpd-24-centos7 容器打包 docker commit -m "描述信息" -a "作者信息" 容器ID/容器名称 ⾃定义镜像名称:⾃定义标签 docker commit -m "ws" -a "ws" cm01 wsapache:v1.0
1 2 镜像封装 docker save 镜像名称:标签 -o 镜像打包的⽂件名
1 2 3 4 5 6 7 8 关闭容器 docker stop cm01 删除镜像 docker rmi wsapache:v1.0 删除容器 docker rm cm01 通过其他机器打包的镜像包,进行镜像载入到本机 docker load -i wsapache.tar
Docker网络 本文转载自我的CSDN,水印就不去了 https://blog.csdn.net/qq_72569959/article/details/134894177
docker网络原理 与ovs类似,docker容器采用veth-pair + linux bridge (虚拟交换机)的通信方式 以Bridge类型举例
查看得到: 容器外的if20连接了容器cm01的if21网卡 容器外的if22连接了容器cm02的if23网卡 数字不固定,一般宿主机是偶数,容器内是奇数
查看br状态,看到有两个veth-pair网卡连接到了br0
容器内的ip地址通过vRouter的NAT转换成宿主机地址
1 2 3 4 5 6 7 8 9 10 11 12 docker run -dit --name cm01 alpine docker run -dit --name cm02 alpine brctl showmacs docker0 port no mac addr is local ? ageing timer 1 02:42:ac:11:00:02 no 0.14 2 02:42:ac:11:00:03 no 0.14 2 36:5c:3a:ff:64:14 yes 0.00 2 36:5c:3a:ff:64:14 yes 0.00 1 ae:84:17:1c:93:6c yes 0.00 1 ae:84:17:1c:93:6c yes 0.00
docker网络类型 docker默认创建了三种网络类型
1 2 3 4 5 6 docker network ls NETWORK ID NAME DRIVER SCOPE a21005000639 bridge bridge local e6a21ab3e3b4 host host local 6725e5c3cb83 none null local docker network inspect a21005000639
docker共有5种网络类型 ,各有特点
1、none 只有loopback,容器内部无网卡
2、host 容器使用宿主机网络,类似于VMwareworkstation的桥接网络 ————直接共享宿主机的网络状态 ————不同容器之间需要使用不同的IP地址 ————直接访问,效率更高
3、bridge (容器默认使用并连接到docker0网桥) 最常用的方式 ————通过NAT进行访问,外部访问即指定端口号 ————二层通过linux Bridge mac表进行交换 ————三层通过iptables和路由表进行转发 ————经过NAT装换,效率相对较低
4、container 共享容器命名空间 ————主机和主机共享命名空间 ————不同容器之间可以使用相同的IP地址 ————k8s打包pod时使用
5、vxlan cluster 集群网络 ————用于集群内容器实现大二层通信 ———通过安装etcd实现
Bridge网络 创建新的网桥br1 1 2 3 4 5 6 7 8 9 10 11 12 docker network create -d --gateway --subnet docker network create -d bridge br1 docker network rm br1 docker network create -d bridge --subnet 192.168.1.0/24 -- gateway 192.168.1.1 br1 通过查看docker network ls 和brctl show,可以发现都多了一个网桥br1
没有指定子网的情况下,子网会顺延创建,默认的docker0使用的是172.17网段,br1使用172.18网段
1 2 3 4 5 创建新的容器并指定网络 docker run -itd --name cm04 --network br1 alpine docker exec -it cm04 ash ip a 能看到新的容器已经获得了地址
新的br上增加了一个interface
查看iptables
将容器切换网桥 docker network disconnect bridge cm01 #断开连接
docker network connect br1 cm01 #重新连接
docker network inspect br1 #查看br1状态,可以看到有两个容器获得了地址
自定义网桥的域名访问 在用户自定义的网络类型中,自带了域名解析功能,可以使用域名直接进行访问
给容器设置别名来使用网络 1 2 3 4 5 6 7 8 9 10 docker run -itd --name cm01 alpine /bin/ash docker run -itd --name cm02 --link =cm01:test alpine /bin/ash docker exec -it cm01 /bin/ash ip a docker exec -it cm02 /bin/ash ip a
host网络 复制宿主机网络状态,与宿主机共用同一个网络命名空间
1 2 3 docker run -itd --name cm05 --network host alpine docker exec -it cm05 ash ip a
none网络 1 2 3 docker run -itd --name cm08 --network none alpine docker exec -ti cm08 ash ip a
container网络 复制另外容器的网络状态,与另外容器共用同一个网络命名空间
1 2 3 docker run -itd --name cm06 --network container:cm01 alpine docker exec -it cm06 ash ip a
vxlan cluster网络 集群场景下,两个宿主机要跨网段进行大二层交换,需要安装etcd分布式数据库,构建etcd存储,用以同步网络信息
注意:docker版本为Docker 20.10.6,如果不是这个版本可能会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz 我将其放在了根目录下 tar -zxvf etcd-v3.0.12-linux-amd64.tar.gz cd /etcd-v3.0.12-linux-amd64/nohup ./etcd --name docker-node1 --initial-advertise-peer-urls \http://192.168.8.150:2380 \ --listen-peer-urls http://192.168.8.150:2380 \ --advertise-client-urls http://192.168.8.150:2379 \ --listen-client-urls http://192.168.8.150:2379,http://127.0.0.1:2379 \ --initial-cluster-token etcd-cluster \ --initial-cluster docker-node1=http://192.168.8.150:2380,docker-node2=http://192.168.8.148:2380 \ --initial-cluster-state new& cd /etcd-v3.0.12-linux-amd64/nohup ./etcd --name docker-node2 --initial-advertise-peer-urls \http://192.168.8.148:2380 \ --listen-peer-urls http://192.168.8.148:2380 \ --advertise-client-urls http://192.168.8.148:2379 \ --listen-client-urls http://192.168.8.148:2379,http://127.0.0.1:2379 \ --initial-cluster-token etcd-cluster \ --initial-cluster docker-node1=http://192.168.8.150:2380,docker-node2=http://192.168.8.148:2380 \ --initial-cluster-state new& 创建完之后再单开一个terminal ps -ef | grep etcd cd /etcd-v3.0.12-linux-amd64/./etcdctl cluster-health systemctl stop docker.service systemctl stop docker.socket /usr/bin/dockerd -H tcp://0.0.0.0:2375 \ -H unix://var/run/docker.sock \ --cluster-store=etcd://192.168.8.150:2379 \ --cluster-advertise=192.168.8.150:2375& systemctl stop docker.service systemctl stop docker.socket /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \ --cluster-store=etcd://192.168.8.148:2379 \ --cluster-advertise=192.168.8.148:2375& docker network create -d overlay etcd_network docker network ls docker inspect etcd_network 在宿主机2查看与宿主机1一致 docker network ls
Docker存储 通过命令查看存储驱动程序docker info | grep -i storage
#Storage Driver: overlay2
一般采用的都是overlay2
overlay2 不使用volume或bind mount时,默认使用overlay2的Storage Driver,通过merge将容器可读可写层融合在镜像上,其默认挂载路径为/var/lib/docker/overlay2
在创建了容器后,通过df -Th可以看到多了一个overlay [filesystem]挂载路径在/var/lib/docker/overlay2/中,并且容器删除之后就会消失 下面用实验演示一下
1 2 3 4 5 6 7 8 [root@192 ~] 51 [root@192 ~] centos cm01 test [root@192 ~] test [root@192 ~] 49
可以看到删除容器后目录下的条目变少了
如果要进行持久化存储,则可以通过两种方式,volume与bind mount来实现
volume 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 docker run -tid --name centos -v /etc/selinux/ centos ls /var/lib/docker/volumes/a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51/_data/可以看到多了个semanage.conf文件,这是从容器中挂载出的文件,在这个文件中修改时也会将其同步到容器内 列出volume卷 docker volume ls DRIVER VOLUME NAME local a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51查看volume卷详情 docker volume inspect a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51 [ { "CreatedAt" : "2023-12-10T21:04:12+08:00" ,"Driver" : "local" ,"Labels" : {"com.docker.volume.anonymous" : "" }, "Mountpoint" : "/var/lib/docker/volumes/a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51/_data" ,"Name" : "a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51" ,"Options" : null,"Scope" : "local" } ]
特点: 1.Volume完全由Docker管理.是将特定⽬录挂载给容器。 2.使⽤卷Volume时,会在主机上的Docker存储⽬录中创建⼀个新⽬录,Docker会管理该⽬录的内容。 3.Volume的内容存在于容器的⽣命周期之外:删除容器后,Docker数据卷仍然存在。 4.挂载volume时,不需要指定mount源,指定mount point即可。 5.Docker会在/var/lib/docker/volumes路径下为每个volume⽣成⼀个⽬录,作为mount源。 6.若mount point指向容器中的已有⽬录,则该⽬录下的数据会被copy到volume中。 7.若mount point指向容器中的空⽬录,则会⾃动创建所需⽬录。 8.若启动挂载尚不存在的卷的容器,Docker会为⾃动创建卷。 9.volume在使⽤时,可通过ro参数将容器对volume的权限设置为只读。
bind mount 将宿主机上已有的目录或文件mount到容器中
下面这个操作是创建一个http服务器,并且将本地文件挂载到服务展示文件的位置docker run --name web01 -dit -p 8080:80 -v /root/htdocs:/usr/local/apache2/htdocs httpd:2.4
特点: 1.Linux绑定挂载(bind mount)主要作⽤是允许将⼀个⽬录或者⽂件(不是整个设备)挂载到⼀个指定的⽬录上。 2.在该挂载点上进⾏的任何操作,只是发⽣在被挂载的⽬录或者⽂件上,⽽原挂载点的内容则会被隐藏起来且不受影 响。 3.容器运⾏过程中,对bind mount⽬录中改动的数据,将被保存。删除容器后,bind mount中的数据仍然存在。 4.bind mount可以挂载⼀个⽬录到容器,也可以挂载⼀个⽂件到容器。但必须要指定⽬录或⽂件的路径,即mount 源,当然也必须指定mount point。这也限制了容器的可移植性。 5.若将bind mount绑定到容器上的某⾮空⽬录下,则会隐藏容器⽬录下的现有内容。若不希望容器的整个⽬录被覆 盖,可单独挂载某个⽂件。 6.若mount源指向的⽂件或⽬录在宿主机上不存在。则会⾃动创建。 7.使⽤bind mount时,可通过ro参数将容器对数据的权限设置为只读。(设置ro参数后,容器⽆法对数据进⾏修改,但宿主机依旧有权限修改其内容。
Dockerfile的介绍与书写 Dockerfile是一个用于定义Docker镜像的文本文件,包含了一系列的指令和参数,用于指示Docker在构建镜像时应该执行哪些操作,例如基于哪个基础镜像、复制哪些文件到镜像中、运行哪些命令等。
是除了从镜像仓库拉取、解压保存镜像以外的自定义构建镜像的方式,通过docker bulid dockerfile来构建
主要有几个部分组成,包括基础镜像,创建者信息,镜像操作指令,容器启动指令
构建指令:docker build -t=”image-name” <文件目录> –load
#Dockerfile文件指令 #FROM FROM指定基础镜像,这个文件需要在本地有 如果在docker build后增加–load参数 可以去docker官网进行拉取 Dockerfile文件中定义的镜像就以FROM的镜像为基础,可指定tag
#MAINTAINER 是备注,用以指定创建者信息
#COPY 将同目录下的文件复制到镜像中 也可以使用—chown=参数指定权限 格式为 filename path
#ADD 格式同COPY 区别是移动tar文件后会自动解压 docker官方推荐使用COPY
#RUN 说明镜像构建过程中需要运行的命令,每次执行都会增加一层 有shell模式和exec模式 shell模式: 直接使用linux命令即可 exec模式: RUN [“/bin/bash”,”-c”,” yum -y install xxx”] /bin/bash表示解释器位置 -c代表指定后面是要执行的命令
#EXPOSE 声明端口,说明这个端口是容器映射出去的端口 可以指定多个 声明后,docker run -P会随机将宿主机端口映射到声明后的端口
#CMD CMD在docker run命令执行时执行 有shell模式和exec模式 但会被docker run后自带的命令所覆盖 如果使用了ENTRYPOINT指令,作为其默认参数
#ENTERYPOINT 作用于CMD相同 有shell模式和exec模式ENTERYPOINT 不会被docker run后自带的命令覆盖,如果使用了参数–entrypoint则可以覆盖
ENTRYPOINT与CMD混用: ENTRYPOINT [“nginx”,”-c”] CMD [“/nginx.conf”] nginx是nginx的命令行工具 -c代表用xx文件执行该命令 /nginx.conf基于根目录下的nginx.conf运行,即该文件是默认文件 但如果docker run指定了命令,就会覆盖掉CMD指定的文件,转而使用docker run指定的文件
#VOLUME 指定容器内的默认挂载点,使用后会默认把宿主机/var/lib/docker/volumes中挂载到容器中的挂载点,在docker run时可以通过-v手动指定宿主机挂载点 1.持久化存储,避免因为重启导致数据丢失 2.可以通过-v来更好管理存储
#WORKDIR 指定命令的工作目录,需要提前创建好
#ENV 指定环境变量 ENV key=value 例如ENV VERSION= 1.0,就可以使用$VERSION来引用
#USER 用以指定用户和用户组
#ONBUILD 延迟执行创建的命令,在某次构建镜像时不会执行,但下次如果有新的dockerfile使用了本镜像进行镜像构建时,就会执行这条命令。
nginx镜像构建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 mkdir wsdockerfilecp Centos-vault-8.5.2111.repo wsdockerfile/cd wsdockerfile/cat > dockerfile << EOF FROM centos MAINTAINER ws RUN rm -rf /etc/yum.repos.d/* COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/ RUN yum install -y nginx COPY index.html /usr/share/nginx/html/ EXPOSE 80 ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"] EOF echo 123 > index.htmldocker build -t="ws/nginx:v1" . docker images | grep ws/nginx docker run -d -p 80 --name wshttp ws/nginx:v1 docker ps
Docker数据卷容器与备份 数据卷容器的概念:其他容器通过这个容器实现数据共享,这个容器就叫数据卷容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 cat > dockerfile << EOF FROM centos VOLUME ["/volume1","/volume2"] CMD /bin/bash EOF docker build -t="volume" . docker run -itd --name data-container volume docker exec -it data-container /bin/bash cd volume1 && touch 123 && exit docker run --name data-container2 --volumes-from data-container -itd centos /bin/bash docker exec -it data-container2 /bin/bash ls volume1docker run --volumes-from data-container2 -v /root/backup:/backup \ --name backup-container centos tar zcvf /backup/volume1.tar.gz /volume1 ls /root/backup/docker rm -f data-container2 docker run --volumes-from backup-container \ -v /root/backup:/backup centos tar zxvf /backup/volume1.tar.gz -C / docker exec -it data-container2 /bin/bash ls volume1
docker资源配额 Docker资源配额指的是对Docker容器或服务在系统资源使用方面的限制。 通过资源配额,可以控制和限制Docker容器可以使用的CPU、内存、磁盘空间和网络带宽等资源。
需要根据应用程序的需求和系统环境来设置适当的资源配额。过于严格的配额可能导致应用程序性能下降,而过于宽松的配额可能会导致资源浪费和冲突,资源配额提供了更好的资源控制和管理机制,以确保容器化环境的稳定性和性能。
CPU资源配额 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 docker run --help | grep cpu --cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota --cpu-rt-period int Limit CPU real-time period in microseconds --cpu-rt-runtime int Limit CPU real-time runtime in microseconds -c, --cpu-shares int CPU shares (relative weight) --cpus decimal Number of CPUs --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1) CPU shares在创建容器时指定容器所使用的CPU份额值 是一个相对的加权值,不能保证获取绝对的core数量,默认docker容器cpu份额为1024 份额为1000的A容器和2000的B容器,B获取CPU占用时间的是A的两倍 如果CPU是充足,那么A和B都能获得充足的CPU docker run -itd --name cpu1 --cpu-shares 1000 centos /bin/bash docker exec -it cpu1 /bin/bash cat /sys/fs/cgroup/cpu/cpu.shares可以控制容器运行限定使用哪些cpu内核和内存节点 更适用于具有NUMA拓扑(具有多CPU、多内存节点)的服务器 8 docker run -itd --name cpu1 --cpuset-cpus 0,1 centos /bin/bash docker run -itd --name cpu1 --cpuset-cpus 0,1 --cpu-shares 1000 centos /bin/bash docker exec -it cpu1 /bin/bash rm -rf /etc/yum.repos.d/* && exit docker cp Centos-vault-8.5.2111.repo cpu1:/etc/yum.repos.d/ docker run -itd --name cpu2 --cpuset-cpus 0,1 --cpu-shares 2000 centos /bin/bash docker exec -it cpu2 /bin/bash rm -rf /etc/yum.repos.d/* && exit docker cp Centos-vault-8.5.2111.repo cpu2:/etc/yum.repos.d/ docker exec -it cpu1 yum install -y epel-release docker exec -it cpu1 yum install -y stress docker exec -it cpu2 yum install -y epel-release docker exec -it cpu2 yum install -y stress stress --help docker exec -it cpu1 /bin/bash stress -c 2 --timeout 5m docker exec -it cpu2 /bin/bash stress -c 2 --timeout 5m
内存资源配额 1 2 3 4 5 6 7 8 9 10 11 根据容器所运行的业务,配置相应最大内存,防止用太多影响其他的业务 docker run --help | grep -i memory --kernel-memory bytes Kernel memory limit -m, --memory bytes Memory limit --memory-reservation bytes Memory soft limit --memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap --memory-swappiness int Tune container memory swappiness (0 to 100) (default -1) docker run -itd --name mem1 -m 1g centos docker exec -it mem1 cat /sys/fs/cgroup/memory/memory.limit_in_bytes 1073741824
IO资源配额 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 控制IO资源 docker run --help | grep write --device-write-bps list Limit write rate (bytes per second) to a device (default []) --device-write-iops list Limit write rate (IO per second) to a device (default []) docker run --help | grep read --device-read-bps list Limit read rate (bytes per second) from a device (default []) --device-read-iops list Limit read rate (IO per second) from a device (default []) docker run -it -v /test/:/test/ --device /dev/sda:/dev/sda \ --device-write-bps /dev/sda:1mb --name io centos /bin/bash time dd if =/dev/sda of=/test/transblock bs=1M count=60 oflag=direct,nonblock
docker的结束运行资源释放 1 2 3 4 5 6 7 8 设置容器结束运行后自动释放资源,适用于一次性的容器如测试容器 如果容器是异常退出了也会被删除 docker run --help | grep rm --rm Automatically remove the container when it exits docker run -it --rm --name rmtest alpine sleep 5 docker ps -a | grep rm