Docker 容器技术初探

文章目录

  • Docker 容器技术初探
    • 一、 docker 简介
      • 1. 容器简介
        • ① 容器是什么
        • ② 容器和虚拟机的区别
        • ③ 为什么使用容器
        • ④ docker 和容器的关系
      • 2. 为什么需要 docker?
      • 3. docker 核心概念
      • 4. docker 引擎与工作原理
    • 二、 docker 环境准备
      • 1. 系统环境
      • 2. docker 安装
    • 三、docker 的使用
      • 1. 镜像学习
        • ① hello-world 镜像
        • ② ubuntu bash 镜像
        • ③ httpd 镜像
        • ④ 镜像的分层结构
      • 2. docker 常用命令
      • 3. MySQL与容器化
        • ① 下载拉取 MySQL 镜像
        • ② 构建 docker 镜像
          • 1)Dockerfile
          • 2)Dockerfile 常用指令
          • 3)编辑 Dockerfile
          • 4)构建和运行镜像
        • ③ 使用 MySQL 镜像
        • ④ Docker compose 与多容器应用自动化部署
      • 4. docker 网络
      • 5. docker 仓库 (Registry)
        • ① 常用仓库操作
    • 四、参考文章

一、 docker 简介

1. 容器简介

① 容器是什么

  • 容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。

容器由两部分组成:

  • 应用程序
  • 依赖(应用程序需要的库或其他软件)

② 容器和虚拟机的区别

  • 虚拟机需要模拟整个操作系统。而容器运行在 Host 操作系统的用户空间,与操作系统的其他进程隔离,所有的容器共享同一个 Host OS,这使得容器在体积上比虚拟机小很多。
  • 启动容器不需要启动整个操作系统,所以容器部署和启动速度更快,开销更小,也更容易迁移。

③ 为什么使用容器

容器使软件具备了超强的可移植能力。

  • 现今的软件应用往往依赖多种服务,这些服务也有自己的依赖,同时应用可能需要被部署或迁移到不同的环境,需要一种通用的解决办法使得服务在不同的环境下都能顺利运行。

容器有着可重复性和环境隔离。

  • 开发人员只需为应用创建一次运行环境,然后打包成容器便可在其他机器上运行。另外,容器环境与所在的 Host 环境是隔离的。

配置好标准的环境,服务器就可以运行任何容器

  • 运维人员的工作变得更高效,一致和可重复。容器消除了开发、测试、生产环境的不一致性。

④ docker 和容器的关系

  • Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 机器上,也可以实现虚拟化。
  • 从 docker 的 logo 我们可以看出它采用了集装箱原理。在没有使用集装箱的情况下,我们需要考虑不同形状、尺寸的货物怎么安放,货物与货物之间是否能堆叠,这无疑是很繁琐的事情。
  • 有了集装箱(容器),我们就能将不同的货物放入集装箱之内这样就能以同样的方式来存放货物,实现了标准化。

2. 为什么需要 docker?

  • 灵活:即使是最复杂的应用也可以容器化。
  • 轻量:容器是进程,能利用并共享主机操作系统内核。
  • 替换:可以即时部署更新和升级容器。
  • 便携:可以在本地构建,部署到云并在任何地方运行。
  • 扩展:您可以增加并自动分发容器副本。
  • 组合: 您可以自由地组合(stack)服务

3. docker 核心概念

  • 镜像(image) – 类比执行程序,一个可执行的包,包含运行应用程序所需的一切——代码、运行时、库、环境变量和配置文件。
  • 容器(Container) – 类比进程,镜像的运行时实例——镜像在执行时在内存中成为什么(即带有状态的镜像,或用户进程)
  • 仓库(Registry) – 类比 repository,存放不同版本镜像的地方
  • 主机(Host / Node) – 运行容器的服务器
  • 服务(Service) – 一个镜像之上运行的一组可伸缩的容器集合,运行在一个容器集群中提供同一功能服务
  • 栈(Stack) / 命名空间(Namaspace) / 应用(Application) – 被编排的、可伸缩的一组相互依赖的服务,构成的一个应用

4. docker 引擎与工作原理

二、 docker 环境准备

1. 系统环境

  • 硬件信息:virtual box 虚拟机(内存5G、磁盘20G)
  • 操作系统:Centos 7
  • 编程语言:go version go1.13.1 linux/amd64
  • 如果你不是 root 用户,请将用户加入 docker 用户组,具体做法可参考笔者的另一篇博客 Docker 安装使用过程的坑

2. docker 安装

  • 如果之前安装过 docker,请先删除
sudo yum remove docker docker-common docker-selinux docker-engine

  • 安装依赖,期间可能报错 failure: repodata/repomd.xml from mirrors.aliyun.com_docker-ce_linux_centos_docker-ce.pro,具体做法可参考笔者的另一篇博客 Docker 安装使用过程的坑
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

  • 下载 repo 文件
wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo

  • 把软件仓库地址替换为清华源
sudo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
  • 安装
sudo yum makecache fast
sudo yum install docker-ce


  • 检查 docker 安装,输出 Docker 版本号
docker version

三、docker 的使用

1. 镜像学习

镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器。可以运行镜像检查是否成功安装

① hello-world 镜像

  • hello-world 镜像是 Docker 官方提供的一个镜像,我们执行如下操作运行镜像 hello-world
docker run hello-world
  • 首次运行会出现找不到 image 'hello-world:latest’ 的情况,不过 docker 会自动从Docker Hub 上获取到最新的 Hello World 镜像,并下载到本地

  • 从上述运行结果的输出,我们可以了解到镜像的运行里面涉及到了容器客户端与容器服务器的交互,以及容器和镜像之间的关系。

② ubuntu bash 镜像

docker run -it ubuntu bash
  • -it 参数,通过终端与进程(容器)交互,stdin,stdout,stderr定向到 TTY
  • 这里可能需要更换为国内镜像(因为默认是从 Docker Hub 拉取镜像,而国内从 Docker Hub 拉取镜像有时会遇到困难),具体做法可参考笔者的另一篇博客 Docker 安装使用过程的坑
  • 输出结果如下

③ httpd 镜像

docker run -d -p 80:80 httpd
  • 下载 httpd 镜像。启动 httpd 容器,并将容器的 80 端口映射到 host 的 80 端口。
  • 打开浏览器输入 localhost ,出现如下界面,表明可以访问容器的 http 服务,容器运行成功

④ 镜像的分层结构

  • Docker 支持通过扩展现有镜像,创建新的镜像。新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。这种做法的最大一个好处就是:共享资源。例如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。
  • 但是,虽然低层的镜像被共享了,不同容器对其进行修改却不会造成混乱,所有的修改会被限制在单个容器内。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。

添加文件:在容器中创建文件时,新文件被添加到容器层中。
读取文件:在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
修改文件:在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
删除文件:在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

  • 只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。
  • 容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

2. docker 常用命令

  • docker run/build
  • build 构建镜像,run 运行镜像创建容器
  • docker images
  • 查看本地镜像库内容

REPOSITORY:镜像所属仓库名称
TAG:镜像标签。默认是latest,表示最新
IMAGE ID:镜像ID,表示镜像唯一标标识
CREATED:镜像创建时间
SIZE:镜像大小

  • docker ps [-a]
  • 查看正在运行的容器,加上 -a 查看所有容器

CONTAINER_ID:表示容器ID
IMAGE:表示镜像名称
IMAGE:表示镜像名称
CREATED:表示容器创建时间
STATUS:表示容器运行状态。UP表示运行中,Exited表示已停止
PORTS:表示容器对外的端口号
NAMES:表示容器名称,该名称默认由Docker自动生成,也可使用docker run命令的–name选项自定指定

  • docker stop/kill
  • 安全停止/直接杀死正在运行的容器
  • docker --help
  • 获得帮助

– 基本选项
– 管理命令(至少掌握 container, image, network, volume)
– 常用命令
• 例如: docker images 等价于 docker image ls
• 例如: docker ps 等价于 docker container ls

  • docker network
  • 网络相关命令
  • 继续运行原容器并进入
~]# docker restart frosty_goodall
~]# docker ps
~]# docker attach frosty_goodall
root@e2442527555f:/# exit

3. MySQL与容器化

① 下载拉取 MySQL 镜像

  • 执行该命令后,Docker 会从 Docker Hub 中的 mysql 仓库下载最新版镜像

② 构建 docker 镜像

1)Dockerfile

构建镜像有两种方式

  • 使用 docker commit 命令
  • 或通过 Dockerfile 构建文件,是一般使用的方式

Dockerfile 是一个文本文件,记录了镜像构建的所有步骤。

  • 具体操作主要是拉取源,声明工作目录,导入项目,执行项目的运行步骤
2)Dockerfile 常用指令
指令 作用
FROM 指定 base 镜像
COPY 将文件从 build context 复制到镜像
ENV 设置环境变量,环境变量可被后面的指令使用
EXPOSE 指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来
VOLUME 将文件或目录声明为 volume
RUN 在容器中运行指定的命令
CMD 容器启动时运行指定的命令。Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 可以被 docker run 之后的参数替换
ENTRYPOINT 设置容器启动时运行的命令
3)编辑 Dockerfile
  • 以下是一个 Dockerfile 的实例
  • 从终端进入 dockerfile
mkdir mydock && cd mydock
vim dockerfile
  • 在文件中输入以下内容
  • 在该文件中,我们指明镜像基于 ubuntu:latest 镜像,镜像启动后运行 top -b -c 命令。
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
4)构建和运行镜像
  • 构建镜像
  • 运行镜像
  • -it 表示可交互式的 TTY 界面,-rm 表示容器运行完毕后删除此容器

③ 使用 MySQL 镜像

  • 启动服务器
  • 通过 -p 进行端口映射
  • 通过 -e 设置容器的环境变量参数
  • 启动 MySQL 客户端

-it 等价于 -i -t ,表示使用当前 stdin 和 stdout 作为该进程的 io
–rm , 当该进程结束时,自动清理该容器的文件系统空间
–net host,表示容器使用当前主机的网络环境

  • 数据库文件位置
  • Dockerfile 的 VOLUME /var/lib/mysql 的含义

– 每次启动 mysql 容器, docker 创建一个文件卷挂载在容器内/var/lib/mysql位置
– 这个卷在主机(host)的 /var/lib/docker/volumes/ 目录下

  • 创建卷并挂载
  • 将自己定义的数据卷挂载在 /var/lib/mysql
  • 启动客户端连接服务器
  • 使用 --link 使得 myclient 和 hellomysql 容器链接在一起
  • 客户端容器内可以使用 mysql 这个别名访问服务器
  • 启动 bash 命令后,输入 env 查看环境变量
  • 启动 mysql 客户端链接到服务器
  • 挂载现有数据库
  • 官网案例:
docker run -v "$PWD/data":/var/lib/mysql --user 1000:1000 --name
some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
  • 修改容器配置
  • 官网案例:
docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

④ Docker compose 与多容器应用自动化部署

  • Docker Compose 是一个多容器应用自动化部署工具,可大大提高容器部署效率,其通过解析 docker-compose.yml 文件中的配置,实现容器的自动化部署。
  • 下载 docker-compose(容器编排的原型)
  • 有可能会显示 ”没有可用软件包“,这时需要离线下载安装,具体做法可参考笔者的另一篇博客 Docker 安装使用过程的坑
yum install docker-compose
  • 授权和查看版本
  • 创建目录并编写 stack.yml
  • 我们声明了两个 services ,分别是 dbadminer
  • db 中,我们指明了所使用的镜像、密码配置和重启策略;
  • adminer 中,我们指明了所使用的镜像、重启策略和端口映射。
version: '3.1'
services:db:image: mysql:5.7command: --default-authentication-plugin=mysql_native_passwordrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: 19970805adminer:image: adminerrestart: alwaysports:- 8080:8080
  • 通过执行 docker-compose up -d 命令,我们即可启动 db 和 adminer 两个容器
docker-compose -f stack.yml up -d

  • 我们可在浏览器中访问 :8080 端口,进入 Adminer 管理页面
  • 输入 db 用户名 root 和密码后,即可进入到数据库管理页面
  • 可以执行以下命令来终止上述两个容器的运行
docker-compose down

4. docker 网络

  • 管理容器网络

  • 自定义容器网络,备制支持 ifconfigping 命令的 ubuntu 容器



  • 启动另一个命令窗口,由容器制作镜像

  • 创建自定义网络

  • 在另外两个窗口分别创建 u1,u2 容器网络

docker run --name u1 -it -p 8080:80 --net mynet --rm ubuntu:net bash
docker run --name u2 --net mynet -it --rm ubuntu:net bash

  • 执行以下命令
[root@localhost beilineili]# docker inspect u1
[{"Id": "243cd28b9df8cb89d41bc90fab534d0d5f9839e1cfb6dea7541b443b9d6fbf3e","Created": "2020-12-26T07:35:39.72179261Z","Path": "bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 10227,"ExitCode": 0,"Error": "","StartedAt": "2020-12-26T07:35:40.247350341Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:4229b24e447b5187e2db1ab328caf88b7c7e15e7dd0f31baa0f74a6116366471","ResolvConfPath": "/var/lib/docker/containers/243cd28b9df8cb89d41bc90fab534d0d5f9839e1cfb6dea7541b443b9d6fbf3e/resolv.conf","HostnamePath": "/var/lib/docker/containers/243cd28b9df8cb89d41bc90fab534d0d5f9839e1cfb6dea7541b443b9d6fbf3e/hostname","HostsPath": "/var/lib/docker/containers/243cd28b9df8cb89d41bc90fab534d0d5f9839e1cfb6dea7541b443b9d6fbf3e/hosts","LogPath": "/var/lib/docker/containers/243cd28b9df8cb89d41bc90fab534d0d5f9839e1cfb6dea7541b443b9d6fbf3e/243cd28b9df8cb89d41bc90fab534d0d5f9839e1cfb6dea7541b443b9d6fbf3e-json.log","Name": "/u1","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "mynet","PortBindings": {"80/tcp": [{"HostIp": "","HostPort": "8082"}]},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": true,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/ff3ce156d5aca31ec2fe109f12024633a7c9a1e9ecc40b11c82bbc9388b6c946-init/diff:/var/lib/docker/overlay2/9fc69e17121896d1357445fa9e01f2f9542f5d16505b384d39d3f7f2ac4c04cf/diff:/var/lib/docker/overlay2/695290cd3d06c60f2631255a67cbd585a52e2b2080ef481c2483f3b174adb4f2/diff:/var/lib/docker/overlay2/72e5de74f595ffbbd0c8ea8905f176bf1104d3483e1d33a637b76953e2607b67/diff:/var/lib/docker/overlay2/da0f84bbb5974a5eb0fd4b77d65516cbc7e1df4c65a80a0c3de81efe7910153a/diff","MergedDir": "/var/lib/docker/overlay2/ff3ce156d5aca31ec2fe109f12024633a7c9a1e9ecc40b11c82bbc9388b6c946/merged","UpperDir": "/var/lib/docker/overlay2/ff3ce156d5aca31ec2fe109f12024633a7c9a1e9ecc40b11c82bbc9388b6c946/diff","WorkDir": "/var/lib/docker/overlay2/ff3ce156d5aca31ec2fe109f12024633a7c9a1e9ecc40b11c82bbc9388b6c946/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "243cd28b9df8","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"ExposedPorts": {"80/tcp": {}},"Tty": true,"OpenStdin": true,"StdinOnce": true,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["bash"],"Image": "ubuntu:net","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {}},"NetworkSettings": {"Bridge": "","SandboxID": "89b67126e91ef207bfe5f812edca9a2addaad2ce76b915397bfd49970aebff05","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {"80/tcp": [{"HostIp": "0.0.0.0","HostPort": "8082"}]},"SandboxKey": "/var/run/docker/netns/89b67126e91e","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "","Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","MacAddress": "","Networks": {"mynet": {"IPAMConfig": null,"Links": null,"Aliases": ["243cd28b9df8"],"NetworkID": "e2be683e596b3d5fa651af6b9cccd79dc386aeb5d479b285156b1e8a515ee432","EndpointID": "2fcb9b77d2b0710b18d3e1f0d3e514e1bd5f9b9a6f57ed242a9af219ac57b3a0","Gateway": "172.19.0.1","IPAddress": "172.19.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:13:00:02","DriverOpts": null}}}}
]
[root@localhost beilineili]# docker network connect bridge u1
[root@localhost beilineili]# docker network disconnect mynet u1

5. docker 仓库 (Registry)

以阿里云容器镜像服务的教程如下:

  • 访问 阿里云
  • 注册一个账号
  • 选择“容器镜像服务”

① 常用仓库操作

  • 上传 hello-world 镜像
• 登陆 docker login --username= registry.cn-shenzhen.aliyuncs.com • 标签 docker tag hello-world registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:helloworld • 上传 docker push registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:hello-world • 下载 docker push registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:hello-world • 标签 docker tag registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:hello-world helloworld • 删除 docker rmi registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:hello-world • 运行 docker run --rm hello-world • 退出 docker logout registry.cn-shenzhen.aliyuncs.com
  • 检查 docker 的状态
docker info … … docker info --format {{.ServerVersion}}
  • 查看容器内进程
Docker top Docker stats
  • 容器详细信息
docker inspect … … docker inspect -f '{{.NetworkSettings.IPAddress}}' 084f46eddf33 172.17.0.2
  • 容器的日志 – 容器应用的 stdout 与 stderr 输出
  • 容器日志查看
~]# docker logs 084f46eddf33
root@084f46eddf33:/# ll
total 12
drwxr-xr-x. 1 root root 43 Dec 13 13:46 ./
drwxr-xr-x. 1 root root 43 Dec 13 13:46 ../
-rwxr-xr-x. 1 root root 0 Dec 13 13:46 .dockerenv*
drwxr-xr-x. 2 root root 4096 Dec 12 03:44 bin/
…
~]# docker logs --tail 2 084f46eddf33
drwxr-xr-x. 10 root root 97 Dec 10 08:42 usr/
drwxr-xr-x. 11 root root 4096 Dec 10 08:42 var/
  • 日志的重要性!-- 调试、分析

四、参考文章

  • 云生态 - 容器作为服务(CaaS)
  • 清华大学开源软件镜像站
  • MySQL 与容器化
  • CentOS 安装 docker 中文指南
  • mysql 客户端基本操作
  • 《每天5分钟玩转 Docker 容器技术》教程目录
  • 笔者的另一篇博客 Docker 安装使用过程的坑

Docker 容器技术初探相关推荐

  1. 用 Label 控制 Service 的位置 - 每天5分钟玩转 Docker 容器技术(106)

    上一节我们讨论了 Service 部署的两种模式:global mode 和 replicated mode.无论采用 global mode 还是 replicated mode,副本运行在哪些节点 ...

  2. 如何用 Graylog 管理日志?- 每天5分钟玩转 Docker 容器技术(93)

    上一节已经部署好了 Graylog,现在学习如何用它来管理日志. 首先启动测试容器. docker run -d \ --log-driver=gelf \ --log-opt gelf-addres ...

  3. 日志管理之 Docker logs - 每天5分钟玩转 Docker 容器技术(87)

    高效的监控和日志管理对保持生产系统持续稳定地运行以及排查问题至关重要. 在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要.考虑到容器短暂和不固定的生命周期,当我们需 ...

  4. k8s 重要概念 - 每天5分钟玩转 Docker 容器技术(117)

    在实践之前,必须先学习 Kubernetes 的几个重要概念,它们是组成 Kubernetes 集群的基石. Cluster  Cluster 是计算.存储和网络资源的集合,Kubernetes 利用 ...

  5. 回收 PV - 每天5分钟玩转 Docker 容器技术(152)

    当 PV 不再需要时,可通过删除 PVC 回收. 当 PVC mypvc1 被删除后,我们发现 Kubernetes 启动了一个新 Pod recycler-for-mypv1,这个 Pod 的作用就 ...

  6. DaemonSet 典型应用场景 - 每天5分钟玩转 Docker 容器技术(129)

    Deployment 部署的副本 Pod 会分布在各个 Node 上,每个 Node 都可能运行好几个副本.DaemonSet 的不同之处在于:每个 Node 上最多只能运行一个副本. DaemonS ...

  7. Swarm 如何存储数据?- 每天5分钟玩转 Docker 容器技术(103)

    service 的容器副本会 scale up/down,会 failover,会在不同的主机上创建和销毁,这就引出一个问题,如果 service 有要管理的数据,那么这些数据应该如何存放呢? 选项一 ...

  8. Swarm 如何实现 Failover?- 每天5分钟玩转 Docker 容器技术(98)

    故障是在所难免的,容器可能崩溃,Docker Host 可能宕机,不过幸运的是,Swarm 已经内置了 failover 策略. 创建 service 的时候,我们没有告诉 swarm 发生故障时该如 ...

  9. 如何安装和配置 Rex-Ray?- 每天5分钟玩转 Docker 容器技术(74)

    2019独角兽企业重金招聘Python工程师标准>>> Rex-Ray 是一个优秀的 Docker volume driver,本节将演示其安装和配置方法. Rex-Ray 以 st ...

最新文章

  1. R使用交叉验证(cross validation)进行机器学习模型性能评估
  2. ORCAD常用元件库说明
  3. Java报异常时getMessage()方法返回null
  4. python机器学习及实践_Python机器学习及实践
  5. boost::math模块非有限信号 NaN 环回测试
  6. ubuntu联网_Ubuntu物联网操作系统新版发布,支持10年安全更新,镜像仅280M
  7. 块级元素(HTML、CSS)
  8. BZOJ 1878: [SDOI2009]HH的项链【莫队】
  9. bochs镜像java模拟器_bochs WIN7 IMG镜像文件
  10. 笔记本计算机运行程序,这几招让你的笔记本电脑运行速度变快 必学技巧
  11. 【neusoft】 Linux 的学习与使用
  12. LocalDateTime与DateTimeFormatter,毫秒值,时间和文本转换
  13. gzdeflate函数_gzdeflate函数
  14. oracle导入.dmp,oracle导入.dmp脚本
  15. 泛微文书定确保电子档案移交接收过程:真实、完整、可用和安全
  16. 基于改进二进制粒子群算法的配电网重构(matlab实现)
  17. 复盘:智能座舱系列文六- 它的3种交互方式之显式交互(语音以及显示)
  18. MQTT协议快速了解
  19. 用java的swing写了个图片标注工具
  20. 在cesium上面创建一个显示隐藏功能和移动的功能,附加相机飞入

热门文章

  1. 前端生成唯一id UUID
  2. JsonCpp库遍历
  3. 哈夫曼树(模拟+哈夫曼树+最小WPL)
  4. LeetCode:1287. Element Appearing More Than 25% In Sorted Array - Python
  5. JsonParser
  6. python填补缺失值数据驱动代码_python填补缺失值数据驱动代码_python数据预处理之缺失值的各种填补方式...
  7. LTE终端状态汇总:
  8. HTML5+CSS3小实例:3D旋转木马相册
  9. 冰箱中的爱马仕没跑了,用COLMO来开启你的美好新春吧
  10. 医院病历的中英文翻译,医生病历本翻译