Docker 镜像管理

Docker 镜像运行流程 Docker 镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动 Docker 容器 采用分层构建机制,最底层为 bootfs,其之为 rootfs,为了确保用户空间可以正常引导 bootfs:用于系统引导的文件系统,包括 bootloader 和 kernel,在内核中进行构建的,用户使用时是看不到并且体会不到的 rootfs:位于 bootfs 之上,表现为 Docker 容器的根文件系统 传统模式中,系统启动时,内核挂载 rootfs 时会首先将其挂载为只读模式,完整性自检完成后,将其重新挂载为读写模式 docker 中,rootfs 由内核挂载为只读模式,而后通过联合挂载技术额外挂载一个可写层。 Docker Image Layer 位于下层的镜像称之为父镜像,最底层的称为基础镜像。 最上层为 “可读写“ 层,其下的均为 ”只读“ 层 bootloader 层,在内核中,只是为了创建一个容器,并引导容器运行。容器创建完成并引导成功后,那么就会卸载 bootloader 层(在内存中)。 base image 层,是在用户空间中,是一个只读层,是一个基础镜像层。 image 层(add emacs),类似于 vim 的一层 image 层(add apache),是一个应用程序的层,只读层 writable 层,可写层,因为镜像都是只读的,所以当用户在写入或者是修改时,会在这个镜像的上方新建一个写入层。当删除容器时,容器的可写层会一并被删除。 Aufs(Storage Driver) 高级多层统一文件系统,简称 Aufs。前身是 UnionFS,在 2006 年诞生。aufs 一直都不是内核的代码。 Docker 最初使用 aufs 作为容器文件系统层,目前仍然作为存储后端之一来支持。 overlayfs 是 aufs 的竞争版。Docker 的分层镜像,除了 aufs,docker 还支持 btrfs,devicemapper 和 vfs 等。 ...

November 11, 2020

Docker LXC

虚拟化类别 主机级虚拟化 类型 1 虚拟化 直接在硬件之上安装虚拟机,称为 Hypervisor,也就意味着在硬件之上不需要安装宿主机操作系统。在 Hypervisor 安装操作系统。 类型 2 虚拟化 vmware virtualbox,在硬件之上安装操作系统,称为 hostOS 也称为宿主机,然后在宿主机之上安装 VMM(Virtual Machine Manager) 主机虚拟化的缺点 资源开销较大,例如有时仅仅需要创建一个应用程序而已,但是就必须要使用传统的主机级虚拟化安装一个操作系统在操作系统上安装应用程序。 这就造成了资源浪费,因为我们的目的仅仅是要上线一个应用程序而已。 容器级虚拟化技术 通过内核的 namespace 和 chroot 来实现容器级的虚拟化,让各个容器共享内核。并通过内核的 namespace 中的六个隔离和系统调用实现容器的划分及虚拟化。 使用容器的初衷 为了让环境隔离,例如需要上线两个 nginx 服务,并且都需要使用 80 端口,但是一个主机仅有一个 80 端口套接字,无法实现。所以需要使用虚拟机。 让多个虚拟机是互相不可达的。 容器技术 运行进程不受其他进程干扰,在使用容器时,创建出多个用户空间。在多个用户空间中运行单独的进程,那么这个用户空间就称之为容器。多个用户空间会共同使用一个单独的内核,一般情况下会使用第一个用户空间是有特权的用户空间,并且会使用这个有特权的用户空间来控制其他的用户空间。 Docker 的诞生 jail 最初出现 jail 的目的,是为了安全。因为就算是黑客攻击了这个容器,那么攻陷的也仅仅是个容器,到达的资源边界就是容器的边界。 vserver(chroot) 将 jail 技术复刻到 linux 之后的技术称之为 chroot(切根),当切根后,那么实现的就是让单个用户在一个目录中运行,并且可以让这个用户在这个目录中认为这个就是根目录。 相关系统调用 clone() 创建进程的系统调用 setns() 创建名称空间后将进程放置到名称空间的调用 LXC(linuxX Container)的诞生 Docker 是一个应用工具,并且是一个 LXC 增强版。 为什么需要 LXC,因为之前的 vserver 技术需要来调用系统的调用才能实现需要的功能,所以这种方法不易于大众来使用。 所以 linux 公司就研发了一种 LinuX Container 技术。 ...

November 10, 2020

Docker 简介

Docker 简介 Docker 有一个守护程序,一直监听在套接字之上。 使用镜像的流程 从远程 registry 下载镜像,下载到本地后存储到 image 仓库中。然后通过后台的 libcontainer 引擎将镜像加载到容器中。 Docker 付费版和社区版 Docker-ee 是付费版,Docker-ce 是社区版,并且是免费版。 Docker 组成 Docker daemon 运行的守护进程 Docker client 客户端的运行 Docker registries 镜像仓库,最著名的有 Docker 官方的镜像仓库,但是本地用户也可以创建一个本地的镜像仓库。 镜像和容器的关系 镜像是静态的,容器是动态的,并且有生命周期。要想运行容器 Docker 的资源对象 images 镜像,支持增删改查 containers 容器,支持增删改查 networks 网络,单独支持增删改查 volumes 卷,增删改查 plugins 插件,增删改查 Docker 的安装 找到阿里云源或者是清华大学源,都会有 docker 的 yum 源 daemon.json 文件配置 https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file 官方网址 { "authorization-plugins": [], "data-root": "", "dns": [], "dns-opts": [], "dns-search": [], "exec-opts": [], "exec-root": "", "experimental": false, "features": {}, "storage-driver": "", "storage-opts": [], "labels": [], "live-restore": true, "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file":"5", "labels": "somelabel", "env": "os,customer" }, "mtu": 0, "pidfile": "", "cluster-store": "", "cluster-store-opts": {}, "cluster-advertise": "", "max-concurrent-downloads": 3, "max-concurrent-uploads": 5, "default-shm-size": "64M", "shutdown-timeout": 15, "debug": true, "hosts": [], "log-level": "", "tls": true, "tlsverify": true, "tlscacert": "", "tlscert": "", "tlskey": "", "swarm-default-advertise-addr": "", "api-cors-header": "", "selinux-enabled": false, "userns-remap": "", "group": "", "cgroup-parent": "", "default-ulimits": { "nofile": { "Name": "nofile", "Hard": 64000, "Soft": 64000 } }, "init": false, "init-path": "/usr/libexec/docker-init", "ipv6": false, "iptables": false, "ip-forward": false, "ip-masq": false, "userland-proxy": false, "userland-proxy-path": "/usr/libexec/docker-proxy", "ip": "0.0.0.0", "bridge": "", "bip": "", "fixed-cidr": "", "fixed-cidr-v6": "", "default-gateway": "", "default-gateway-v6": "", "icc": false, "raw-logs": false, "allow-nondistributable-artifacts": [], "registry-mirrors": [], "seccomp-profile": "", "insecure-registries": [], "no-new-privileges": false, "default-runtime": "runc", "oom-score-adjust": -500, "node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"], "runtimes": { "cc-runtime": { "path": "/usr/bin/cc-runtime" }, "custom": { "path": "/usr/local/bin/my-runc-replacement", "runtimeArgs": [ "--debug" ] } }, "default-address-pools":[ {"base":"172.80.0.0/16","size":24}, {"base":"172.90.0.0/16","size":24} ] } 指定 docker 版本下载 查看所有版本 [root@centos7_10 ~]# yum list docker-ce.x86_64 --showduplicates 指定下载 apt-get -y install docker-ce=5:18.09.9~3-0~ubuntu-bionic docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic Docker 的进程 dockerd:服务器程序,被 client 直接访问,其父进程为宿主机的 systemd 守护进程 docker-proxy:每个进程 docker-proxy 实现对应一个需要网络通信的容器,管理宿主机和容器的之间端口映射,其父进程 dockerd,如果容器不需要网络则无需启动 containerd:被 dockerd 进程调用以实现与 runc 交互 containerd-shim:真正运行容器的载体,每个容器对应一个 container-shim 进程,其父进程为 containerd Docker 安装源配置 进入网站,下载 repo 源,然后将 repo 源中的源连接替换到repo 源中https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/ ...

November 10, 2020

Docker容器及管理

容器简介 容器就是镜像的运行时示例。正如从虚拟机模板启动 VM 一样,用户也同样可以从单个镜像上启动一个或多个容器。就像使用一个 OS 镜像在 VMware 装多个系统一样。 虚拟机与容器 虚拟机和容器最大的区别是容器更快更加便捷轻量 虚拟机是在操作系统上新建的一个操作系统,不与操作系统共享内核,有自己的操作系统和内核 容器是在操作系统上新建的容器,与操作系统共享内核 启动容器方法 docker container run 命令启动容器,该命令可以携带许多参数。 基础格式 docker container run <image> <app> 中,指定了启动所需的镜像以及要运行的应用。 docker container run -it ubuntu /bin/bash 启动某个 Ubuntu Linux 容器,运行 /bin/bash 作为应用进行启动 -it 参数可以将当前终端连接到容器的 shell 终端之上 容器随着启动运行应用程序的退出而终止。linux 容器会在 /bin/bash 退出后终止。简单的验证方法 docker container run -it [image] sleep 10 这条命令可以验证容器是根据运行在自己身上的应用来决定自己是否正在运行的。 docker container stop 停止容器正在运行的应用 docker container rm 删除容器正在运行的应用 容器和虚拟机 虚拟机与容器都是寄居在物理机上运行的。 虚拟机 虚拟机是将物理机的物理资源通过 Hypervisor 划分成多个 VM 小块并封装,在这个封装的 VM 环境中,安装自己单独的 OS 系统,并且可以在系统上安装相应的应用。一旦 Hypervisor 启动,那么就会占用所有的主机资源。虚拟机是将硬件的物理资源划分,在物理资源上直接创建的虚拟机系统,且整个架构可以装载自定义的操作系统 ...

October 25, 2020

Docker应用容器化

Docker 应用容器化简介 将应用整合到容器并且运行起来的这个过程,成为“容器化”(Containerizing),有时也叫做“docker 化” 容器是为应用而生的,具体来说,容器能够简化应用的构建、部署和运行过程。 容器是为应用而生的,具体来说容器能够简化应用的构建、部署和运行过程。 完整的应用容器化过程 编写应用代码 创建一个 dockerfile,其中包含当前应用的描述、依赖以及该如何运行这个应用 对该 Dockerfile 执行 docker image buuild 命令 等待 Docker 将应用程序构建到 Docker 镜像中 一旦完成了应用容器化(就是将一个应用打包成为一个 Docker 镜像),就能以镜像的形式交付并以容器的方式运行了。 1.获取应用代码 应用代码可以从网盘获取(https://pan.baidu.com/s/150UgIJPvuQUf0yO3KBLegg 提取码:pkx4) 安装解压工具 yum install unzip zip 解压后目录树 [root@centos7 wenjian1]# tree psweb-master/ psweb-master/ ├── app.js ├── circle.yml ├── Dockerfile ├── package.json ├── README.md ├── test │ ├── mocha.opts │ └── test.js └── views └── home.pug 该目录下包含了全部的应用源码,以及包含界面的单元测试的子目录。应用代码准备完成后开始准备 dockerfile 文件。 2. 分析 Dockerfile 如何区分指令是否会新建镜像层 基本原则,如果指令的作用是向镜像中添加新的文件或程序,那么这条指令就会新建镜像层,如果只是告诉 Docker 如何完成构建或者如何运行应用程序,那么就只会增加镜像的元数据。(查看 docker image history 指令中 SIZE字段不为零的指令都会新建镜像层) ...

October 25, 2020

Docker镜像及管理

Docker 镜像概念 可以把镜像理解为 VM 模板,VM 模板就像停止运行的 VM,而 Docker 就像停止运行的容器。就像一个静态的 OS 镜像。 首先需要从镜像仓库拉取镜像,然后使用**镜像可以启动多个容器。**镜像在内部看来有很多层级,但是在外部看来就是一个整体。在镜像中像是集成了一个小 OS,其中镜像中包含了许多必须依赖的内容。 在该前提下,镜像可以理解为一个构建时(build-time)结构,而容器可以理解为一个运行时(run-time)结构 镜像和容器 上图反映了镜像与容器之间的关系,如果镜像没有使用 docker container run 命令运行在容器中时,那么将可以随时删除。但是使用 docker container run 命令运行镜像到容器后,那么两个就会像绑定到一起一样。这时删除镜像将会有错误。 因为镜像正在容器中运行,所以时删除不了的,就类似于你的 OS 镜像在 VMware workstation 中挂载运行时,是无法删除挂载后的镜像的。 镜像的大小 镜像一般都比较小,一般的镜像会包含多个 shell 环境或者是一个 shell 环境,有些镜像为了节省空间只会创建一个 shell,并不会创建多个 shell。 并且镜像中是不包含内核的,会与宿主机共享内核来使用并运行该容器。 例如 ubuntu 的镜像,在官方网站上要近 10G,但是在 docker 镜像中,只需要 110M 就可以下载 Ubuntu 并可以使用该 Ubuntu 的环境。 Hyper-V 容器是个特例,他会运行在轻量级的 VM 上,同时利用 VM 内部的操作系统内核。 拉取镜像 Docker 主机安装之后,本地没有镜像。 通常情况下,镜像会从 Docker Hub 的仓库中拉取。docker image pull alpine:latest 命令会从 docker hub 的 alpine 仓库中拉取标签为 latest 的镜像。默认镜像会存储在 /var/lib/docker/ ...

October 24, 2020

Ansible Role

roles 角色 角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中 运维复杂的场景:建议使用 roles,代码复用度高 roles:多个角色的集合, 可以将多个的role,分别放至roles目录下的独立子目录中 roles 目录结构 bash playbook.yml roles/ project/ tasks/ files/ vars/ templates/ handlers/ default/ meta/ roles 各目录作用 files/ :存放由copy或script模块等调用的文件 templates/:template模块查找所需要模板文件的目录 tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含 handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含 vars/:定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含 meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含 default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低 创建 roles 步骤 创建 role 步骤 Code 1 创建以roles命名的目录 2 在roles目录中分别创建以各角色名称命名的目录,如webservers等 3 在每个角色命名的目录中分别创建files、handlers、tasks、templates和vars等目录;用不到的目录可以创建为空目录,也可以不创建 4 在playbook文件中,调用各角色 目录树结构 bash [root@DESKTOP-NHT2EP5 ansible]#tree . ├── install_httpd.yml └── roles └── httpd ---角色名称 ├── files ---文件位置 │ ├── httpd.conf │ └── index.html ├── handlers ---触发器后执行的文件 │ └── main.yml └── tasks ---tasks 文件存放位置 ├── copy.yml ├── install.yml ├── main.yml └── service.yml playbook 调用角色 第一种方法 yaml --- - hosts: websrvs remote_user: root roles: - mysql - memcached - nginx 第二种方法 键 role 用于指定角色名称,后续的 k/v 用于传递参数给角色 ...

October 20, 2020

Docker引擎

Docker 引擎简介 用来运行和管理容器的核心软件,通常人们会将其指为 docker 或 docker 平台。 基于开放容器计划(OCI)相关标准的要求,docker 引擎操用了模块化的设置原则,其组件是可替换的。 从多个角度来看,Docker 引擎就像汽车引擎——二者都是模块化的,并且由许多可交换的部件组成。 汽车引擎由许多专用的部件协同工作,从而使汽车可以行驶,例如进气管、节气门、气缸、火花塞、排气管等。 Docker 引擎由许多专用的工具协同工作,从而可以创建和运行容器,例如 API、执行驱动、运行时、shim 进程等。 Docker 引擎由如下主要的组件构成:Docker 客户端(Docker Client)、Docker 守护进程(Docker daemon)、containerd 以及 runc。它们共同负责容器的创建和运行。 Docker 首次发布时,Docker 引擎由两个核心组件构成:LXC 和 Docker daemon Docker daemon 是单一的二进制文件,包括诸如 Docker 客户端、Docker API、容器运行时、镜像构建等 LXC 提供了对注入命名空间(Namespace)和控制组(CGroup)等基础工具的操作能力,他们是基于内核的容器虚拟化技术 老版 docker 构成 摆脱 LXC 对 LXC 的依赖始终都是个问题。 首先,LXC 是基于 Linux 的。这对于一个立志于跨平台的项目来说是个问题。 其次,如此核心的组件依赖于外部工具,这会给项目带来巨大风险,甚至影响其发展。 因此,Docker 公司开发了名为 Libcontainer 的自研工具,用于替代LXC。 Libcontainer 的目标是成为与平台无关的工具,可基于不同内核为 Docker 上层提供必要的容器交互功能。 在 Docker 0.9 版本中,Libcontainer 取代 LXC 成为默认的执行驱动。 摒弃大而全的 Docker daemon docker daemon 是什么? docker daemon 是 docker 的守护进程 docker client 命令行与 docker daemon 通信,完成 docker 的相关操作。 ...

October 20, 2020

Ansible Jinja

Jinja语言 jinja2 语言使用字面量,有下面形式: 字符串:使用单引号或双引号 数字:整数,浮点数 列表:[item1, item2, …] 元组:(item1, item2, …) 字典:{key1:value1, key2:value2, …} 布尔型:true/false 算术运算:+, -, *, /, //, %, ** 比较操作:==, !=, >, >=, <, <= 逻辑运算:and,or,not 流表达式:For,If,When 字面量 表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 Python 对象。如”Hello World” 双引号或单引号中间的一切都是字符串。无论何时你需要在模板中使用一个字符串(比如函数调用、过滤器或只是包含或继承一个模板的参数),如42,42.23 数值可以为整数和浮点数。如果有小数点,则为浮点数,否则为整数。在 Python 里, 42 和 42.0 是不一样的 算数运算 Jinja 允许用计算值。支持下面的运算符 +:把两个对象加到一起。通常对象是素质,但是如果两者是字符串或列表,你可以用这 种方式来衔接它们。无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。 2 等于 2 -:用第一个数减去第二个数。 1 等于 1 /:对两个数做除法。返回值会是一个浮点数。 0.5 等于 0.5 //:对两个数做除法,返回整数商。 2 等于 2 %:计算整数除法的余数。 4 等于 4 *:用右边的数乘左边的操作数。 4 会返回 4 。也可以用于重 复一个字符串多次。 NaN会打印 80 个等号的横条 ...

October 18, 2020

Ansible Playbook

Playbook 介绍 playbook 剧本是由一个或多个”play”组成的列表 play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作 Playbook 文件是采用YAML语言编写的 Playbook 命令 格式 bash ansible-playbook <filename.yml> ... [options] 常用选项 bash --syntax-check #语法检查 -C --check #只检测可能会发生的改变,但不真正执行操作 --list-hosts #列出运行任务的主机 jasonchen@DESKTOP-NHT2EP5:~$ ansible-playbook copy.yaml --list-hosts --list-tags #列出tag jasonchen@DESKTOP-NHT2EP5:~$ ansible-playbook copy.yaml --list-tags --list-tasks #列出task jasonchen@DESKTOP-NHT2EP5:~$ ansible-playbook copy.yaml --list-tasks --limit 主机列表 #只针对主机列表中的特定主机执行 jasonchen@DESKTOP-NHT2EP5:~$ ansible-playbook copy.yaml --limit 100.0.0.10 # 设置 limit 的时候,此 IP 必须要存在于脚本定义的 hosts -v -vv -vvv # 显示详细过程,v 越多显示的详细信息越多 Playbook 核心组件 hosts 组件 Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts 用于指定要执行指定任务的主机,须事先定义在主机清单中,然后直接在 yaml 格式的文本中通过 hosts 关键字调用即可 ...

October 18, 2020