Docker学习
前言
Docker应用场景
- 应用程序打包和发布
- 应用程序隔离
- 持续集成
- 部署微服务
- 快速搭建测试环境
- 提供PAAS产品
Docker的基本组成
一、Docker技术原理
1.1、Namespace
Namespace是Linux内核的一项功能,该功能对内核资源进行隔离,是的容器中的进程都可以在单独的命名空间中运行,并且只可以访问当前容器命名空间的资源。Namespace可以个李进程ID、主机名、用户ID、文件名、网络访问和进程件通信等相关资源。
Docker主要用到一下五种命名空间:
pid namespace:用户隔离进程ID
net namespace:隔离网络接口,在虚拟的net namespace内用户可以拥有自己独立的IP、路由、端口等。
mnt namespace:文件系统挂载点隔离;
ipc namespace:信号量,消息队列和共享内存的隔离;
uts namespace:主机名和域名的隔离;
1.2 Cgroup
Cgroups 全程是Control goups ;
Cgroups 是一种 Linux 内核功能,可以限制和隔离进程的资源使用情况(CPU、内存、磁盘 I/O、网络等)。在容器的实现中,Cgroups 通常用来限制容器的 CPU 和内存等资源的使用;
Cgroups有以下功能:
资源限制:限制资源的使用量;
优先级控制:不同组可以有不同的资源使用优先级;
审计:计算控制组的资源使用情况;
控制:控制基础的挂起和恢复。
Cgroups核心概念:
子系统(subsystem):是一个内核组件,一个子系统代表一类资源调度控制器,比如内存子系统,CPU子系统;
控制组(cgroup):表示一组进程和带有参数的子系统的关联关系;
层级树(hierarchy):是一些类控制组安装树状结构组成的,子控制组默认拥有父控制组的属性。
[root@master ~]# mount -t cgroup cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
在CPU下创建cgoup,其实就是创建文件夹
[root@master ~]# cd /sys/fs/cgroup/cpu
[root@master cpu]# ls
cgroup.clone_children cpuacct.stat cpu.cfs_quota_us cpu.stat system.slice
cgroup.event_control cpuacct.usage cpu.rt_period_us mydocker tasks
cgroup.procs cpuacct.usage_percpu cpu.rt_runtime_us notify_on_release user.slice
cgroup.sane_behavior cpu.cfs_period_us cpu.shares release_agent
[root@master cpu]# mkdir mydocker
[root@master mydocker]# ls
cgroup.clone_children cpuacct.stat cpu.cfs_period_us cpu.rt_runtime_us notify_on_release
cgroup.event_control cpuacct.usage cpu.cfs_quota_us cpu.shares tasks
cgroup.procs cpuacct.usage_percpu cpu.rt_period_us cpu.stat
测试Cgroups如何限制docker资源:
首先创建一个容器
[root@master mydocker]# docker run -it -m=1g nginx
进入Cgroup目录,查看限制条件
[root@master docker]# cd /sys/fs/cgroup/memory/docker/9a62a5ce5ff5d53624c0c4fd9c605539354bf66fb8a68dc674eaae520767dce9/ [root@master 9a62a5ce5ff5d53624c0c4fd9c605539354bf66fb8a68dc674eaae520767dce9]# ls cgroup.clone_children memory.kmem.tcp.max_usage_in_bytes memory.oom_control cgroup.event_control memory.kmem.tcp.usage_in_bytes memory.pressure_level cgroup.procs memory.kmem.usage_in_bytes memory.soft_limit_in_bytes memory.failcnt memory.limit_in_bytes memory.stat memory.force_empty memory.max_usage_in_bytes memory.swappiness memory.kmem.failcnt memory.memsw.failcnt memory.usage_in_bytes memory.kmem.limit_in_bytes memory.memsw.limit_in_bytes memory.use_hierarchy memory.kmem.max_usage_in_bytes memory.memsw.max_usage_in_bytes notify_on_release memory.kmem.slabinfo memory.memsw.usage_in_bytes tasks memory.kmem.tcp.failcnt memory.move_charge_at_immigrate memory.kmem.tcp.limit_in_bytes memory.numa_stat [root@master 9a62a5ce5ff5d53624c0c4fd9c605539354bf66fb8a68dc674eaae520767dce9]# cat memory.limit_in_bytes 1073741824
1.3 联合文件系统
联合文件系统,又叫UnionFS,是一种通过常见文件层进程操作的文件系统,因此,联合文件系统非常轻快。Docker使用联合文件系统为容器提供构建层,使得容器可以实现写时复制以及镜像的分层构建和存储。常用的联合文件系统有AUFS、Overlay和Devicemapper等。
二、容器
容器是镜像运行的实体;
容器运行着真正的应用进程;
容器有初建,运行,停止,暂停,和删除五种状态;
在容器内部,无法看到主机上的进程、环境变量、网络信息等。
2.1镜像
镜像是一个只读的Docker容器模版,包含启动容器所需要的所有文件系统结构和内容。
2.2、用docker commit 构建镜像
[root@work02 ~]# docker run -dit --name mybusybox busybox [root@work02 ~]# docker exec -it bdbf14b70bfe /bin/bas / # touch hello.txt&& echo "Hello Docker">hello.txt [root@work02 ~]# docker commit mybusybox mybusybox:hello sha256:6c62f0f461c77a49565aefd00cf8229edfc34694114141851aa274b915b5033c
[root@work02 ~]# docker images | grep mybusybox mybusybox hello 6c62f0f461c7 14 seconds ago 1.24MB
2.3、用dockerfile构建镜像
vi dockerfile FROM busybox COPY test /tmp/test RUN mkdir /tmp/mydocker
用命令创建
[root@work02 dockerfile]# docker build -t mybusybox . Sending build context to Docker daemon 2.56kB Step 1/3 : FROM busybox ---> beae173ccac6 Step 2/3 : COPY test /tmp/test ---> 76e6e0bd958c Step 3/3 : RUN mkdir /tmp/mydocker ---> Running in 7df134fb40cd Removing intermediate container 7df134fb40cd ---> 081f0edaf74c Successfully built 081f0edaf74c Successfully tagged mybusybox:latest
2.4、容器的导入导出
[root@work02 dockerfile]# docker export mybusybox > busy.tar
[root@work02 dockerfile]# ls
busy.tar dockerfile test
导入
[root@work02 dockerfile]# docker import busy.tar busy:test
sha256:e8c3e2ea453447f9306cdd40db134db7317c1027a44ab4afab62e27c74ff6cab
2.5 仓库(Repository)
创建私有镜像
[root@work02 ~]# docker run -d -p 5000:5000 --name registry registry:2.7 Unable to find image 'registry:2.7' locally 2.7: Pulling from library/registry 79e9f2f55bf5: Pulling fs layer 0d96da54f60b: Pull complete 5b27040df4a2: Pull complete e2ead8259a04: Pull complete 3790aef225b9: Pull complete Digest: sha256:169211e20e2f2d5d115674681eb79d21a217b296b43374b8e39f97fcf866b375 Status: Downloaded newer image for registry:2.7 4f7c29cc137fccf97bbd0b5daab8b464197e8b30b589caec048fc4dd5778cb74
查看:
[root@work02 docker]# docker ps | grep registry 4f7c29cc137f registry:2.7 "/entrypoint.sh /etc…" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp registry
将镜像打标签
[root@work02 docker]# docker tag mybusybox:hello localhost:5000/busybox:tt
将镜像推送本地镜像库
[root@work02 docker]# docker push localhost:5000/busybox The push refers to repository [localhost:5000/busybox] 4c87cf4aed66: Pushed 01fd6df81c8e: Pushed tt: digest: sha256:1467a39a1cb5c9346453752ebfbf9162b8a88f9a003256af0201851be00c50a5 size: 734
持久化存储
[root@work02 docker]# docker run -v /var/lib/registry/data:/var/lib/registry -d -p 5000:5000 --name registry registry:2.7a0d52b9e4b567af749c9d3fb6ba411d2abc7c98158b7528f0bd203a6589fd7f3
2.6、容器监控
[root@work02 repositories]# docker stats bdbf14b70bfe CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS bdbf14b70bfe mybusybox 0.00% 116KiB / 1.777GiB 0.01% 814B / 0B 8.19kB / 0B 2 CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS bdbf14b70bfe mybusybox 0.00% 116KiB / 1.777GiB 0.01% 814B / 0B 8.19kB / 0B 2
三、Docker组件构成
3.1、Docker组件-docker
docker是一个二进制文件,对用户可见的操作形式为docker命令,通过docker可以完成所有docker客户端和服务端的通信。
3.2 Docker组件-dockerd
dockerd是用来接收客户端发送的请求,执行具体的处理任务,处理完成后将结果反馈给客户端。
3.3Docker组件-docker-init
init进程可以回收有问题的进程,还可以管理子进程
[root@master ~]# docker run -it --init busybox sh / # ps aux PID USER TIME COMMAND 1 root 0:00 /sbin/docker-init -- sh 6 root 0:00 sh 7 root 0:00 ps aux / #
3.4 Docker组件-docker proxy
docker-proxy主要用来做端口映射,底层依赖于iptables实现。
总结
3.5 containerd组件-containerd
3.6 containerd组件-containerd-shim
将containerd和容器解耦,是containerd-shim作为容器的父进程。
3.7 containerd组件-ctr
containerd-ctr是containerd的客户端,
四、容器网络
CNM(Container Network Mode)容器网络标准。
沙箱(Sandbox):一些列网络堆栈的配置,路由信息,网络信息。
接入点(EndPoint):容器网络的接口;
网络(Network):一组可以相互通信的接入点,多个接入点组成子网。
五、容器存储
[root@master ~]# docker run -dit -v /opt/volume/:/usr/share/nginx/html/nginx nginx
13dcd60ade534916d061457650386f4d3c70f4b0b54caa2f4174f43af7a08d67
创建一个卷
[root@master ~]# docker volume create log-vol log-vol [root@master ~]# docker volume ls DRIVER VOLUME NAME local log-vol
使用创建的卷
[root@master ~]# docker run --mount source=log-vol,target=/tmp/log --name=log-producer -it busybox
/ #
主机与容器间的容器共享:
[root@master ~]# docker run -dit -v /test:/usr/local/data busybox
fa896a395a416251c9bdc264e0abd61ec70c7d72fe9ea67b1355154a93901df2
六、联合文件系统
联合文件系统(Union File System,Unionfs)是一种分层的轻量级文件系统,它可以把多个目录内容挂载同一目录下,从而形成一个单一的文件系统;
联合文件系统是容器和镜像的基础;
因为它可以使Docker把镜像做成分层结构,从而是的镜像的每一层都可以被共享。
查看系统的文件系统
[root@master proc]# cat filesystems
nodev sysfs
nodev rootfs
nodev ramfs
nodev bdev
nodev proc
nodev cgroup
nodev cpuset
nodev tmpfs
nodev devtmpfs
nodev debugfs
nodev securityfs
nodev sockfs
nodev dax
nodev bpf
nodev pipefs
nodev configfs
nodev devpts
nodev hugetlbfs
nodev autofs
nodev pstore
nodev mqueue
xfs
nodev rpc_pipefs
nodev overlay
查看docker使用的文件系统:
[root@master proc]# docker info Client: Debug Mode: false Server: Containers: 6 Running: 2 Paused: 0 Stopped: 4 Images: 2 Server Version: 19.03.9 Storage Driver: overlay2
6.1、DeviceMapper的关键技术
Devicemapper的镜像分层依赖于快照技术实现的。
6.2 OverlayFS文件系统
查看镜像的层级关系
[root@master diff]# docker image inspect nginx
查看overlay2下的目录
[root@master ~]# cd /var/lib/docker/overlay2/ [root@master overlay2]# ls 225cc5cbafbaac1f5636ff5c020be6c1ec077e7861d2805354abe0a274a1374b 225cc5cbafbaac1f5636ff5c020be6c1ec077e7861d2805354abe0a274a1374b-init 35fec7d24e6797a21dbb0392e60afd5c6918faf36a059503b6f2029de92bb0df 35fec7d24e6797a21dbb0392e60afd5c6918faf36a059503b6f2029de92bb0df-init 59f26d7bd304f861e9fe408c5f4eced89850d9f7f5c8c1d4794c6b1ab2b2e385 87bed91f2cbd860508a612f0eac81f118b643d320a7c98571e0a2d995734a614 9796c58571be2087b38be8f37d3136f57112af2176e6fcf6de83ba20bb1ebc6f 9796c58571be2087b38be8f37d3136f57112af2176e6fcf6de83ba20bb1ebc6f-init 9e7226a21cf7de7bf20d1166f3e9d469d1e13c5ee66916109fd8269852528ea6 a0e9c6da9a40df919f865ba83ae329312692b6ae35095aaa77bc4be14b499d5d a0e9c6da9a40df919f865ba83ae329312692b6ae35095aaa77bc4be14b499d5d-init b906a8534b68eb7e6a364dba7259bf2cf03bfcf87284c37068f40a3a8a705d99 backingFsBlockDev bc15fee3cc24db172af42b9f4832c044388b383773372d1915560d578ebf86bb bc15fee3cc24db172af42b9f4832c044388b383773372d1915560d578ebf86bb-init c3e7a1655465d3aeb3ccbcbe2b815de81e4af1e08a42bfafbd6d00dcd286077e cc75ec163a567a38a2c1ff8cab4eb2d57f4d1019db1f72d8a855a1ffd55d20e0 d52bf54a4231ec7590573f4a8b9568e72dcb982c130cecd5be1761bef65bef6d d52bf54a4231ec7590573f4a8b9568e72dcb982c130cecd5be1761bef65bef6d-init eff6bace05849e9e75dc41c526f6fbef193c58df3e94d0fcc5038de29e580a91 l
读取文件:
七、容器编排
7.1、docker compose
mkdir /tmp/wordpress cd /tmp/wordpress touch docker-compose.yml version: '3' services: mysql: image: mysql:5.7 volumes: - mysql_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mywordpress MYSQL_USER: mywordpress MYSQL_PASSWORD: mywordpress wordpress: depends_on: - mysql image: wordpress:php7.4 ports: - "8080:80" restart: always environment: WORDPRESS_DB_HOST: mysql:3306 WORDPRESS_DB_USER: mywordpress WORDPRESS_DB_PASSWORD: mywordpress WORDPRESS_DB_NAME: mywordpress volumes: mysql_data: {}
启动
docker-compose up -d
7.2、Kubernetes
master节点负责对集群中所有容器的调度,各种资源对象的控制,以及响应集群的所有请求。
kube-apiserver:提供API服务,数据存储在etcd中;
kube-schedule:监听未被调度的pod,根据一定的策略将Pod调度到合适的Node节点上运行;
kube-controller-manager:维护集群的状态和资源的管理,每种资源的控制器都是一个独立的协成。
Node节点:
kubelet:通过监听分配到自己运行主机上的Pod对象,确保这些Pod处于运行状态,并且负责定期检查Pod的运行状态,将Pod的运行状态更新到Pod对象中
kube-proxy:每个节点的网络插件,实现了Kubernetes的Service概念,通过维护集群上的网络规则,实现集群内部可以通过负载均衡的方式访问到后端容器。
八、DevOps
DevOps(Development开发,和Operations运维)透过自动化“软件交付”和“架构变更流程”来使得构建,测试,发布能够更快捷、频繁和可靠。
CICD(Continuous Integration持续集成,Continuous Delivery持续交付)