石头记

Docker、Kubernetes、CI/CD 等技术分享

Docker 存储

Docker 为容器提供了两种存放数据的资源:

  • 由 Storage Driver 管理的镜像层和容器层
  • Data Volume

Storage Driver

镜像分层结构

容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。这样的分层结构最大的特性是 Copy-on-Write:

  • 新数据会直接存放在最上面的容器层
  • 修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变
  • 如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件

分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于 Docker storage driver。正是 storage driver 实现了多层数据的堆叠并为用户提供一个单一的合并之后的统一视图。

Docker 支持多种 storage driver,有 AUFS、Device Mapper、Btrfs、OverlayFS、VFS 和 ZFS。它们都能实现分层的架构,同时又有各自的特性。对于 Docker 用户来说,具体选择使用哪个 storage driver 是一个难题,不过 Docker 官方给出了一个简单的答案:优先使用 Linux 发行版默认的 storage driver。Docker 安装时会根据当前系统的配置选择默认的 driver。默认 driver 具有最好的稳定性,因为默认 driver 在发行版上经过了严格的测试。

Docker CE on Ubuntu aufs, devicemapper, overlay2 (Ubuntu 14.04.4 or later, 16.04 or later), overlay, zfs, vfs
Docker CE on Debian aufs, devicemapper, overlay2 (Debian Stretch), overlay, vfs
Docker CE on CentOS devicemapper, vfs
Docker CE on Fedora devicemapper, overlay2 (Fedora 26 or later, experimental), overlay (experimental), vfs

Docker 网络

容器的三种本地网络

none 网络

故名思议,none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。

docker network none

host 网络

连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络。使用 host 网络,容器和宿主机共用 host 网络,当启动服务时应该避免端口冲突。

docker network host

Bridge 网络

Docker 安装时会创建一个命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上。

docker network bridge

Docker 生命周期管理

运行容器

docker run 是启动容器的方法,容器启动后返回的是 “长ID”,我们可以通过这个长ID去访问这个容器,也可以通过启动时指定的名字访问这个容器。docker ps 能够看到容器的“短ID”,通过短ID同样可以访问这个容器,甚至只要能够唯一标识这个容器也可使用更短的ID。

docker run

-d 指定容器以后台方式运行;–restart 指定容器的重启策略,默认值no,容器退出时不要重启,on-failure[:max-retries] 只在容器以非0状态码退出时重启。max-retries可以指定尝试重启容器的次数;always 不管退出状态码是什么始终重启容器。当指定容器退出后,docker daemon将无限次数地重启容器。–name 指定容器的名称。

容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出。理解了这个原理,我们就可以通过执行一个长期运行的命令来保持容器的运行状态。

Docker 镜像

最小镜像

镜像是 Docker 容器的基石,容器是镜像的实例,有了镜像才能启动容器。

镜像到底包含什么呢?容器为什么是轻量级的虚拟化呢?

运行hello world

首先从一个最小的镜像hello-world讲起,hello-world镜像仅有1.85kB,根据经验它肯定是不包括Linux的内核的,因为现在Linux内核大小至少100MB以上。

这么小的镜像,它能运行,是一个完整的镜像,他是怎么构建出来的呢?

hello world dockerfile

这个镜像的构建文件仅有三行,第一行从空白镜像开始构建,第二行拷贝二进制hello程序,第三行运行hello程序。

/hello 就是文件系统的全部内容,连最基本的 /bin,/usr, /lib, /dev 都没有。

Hello Docker

环境选择

容器需要管理工具、运行时和操作系统,我们的选择如下:

  • 管理工具 - Docker Engine
    因为 Docker 最流行使用最广泛

  • 运行时 - runc
    Docker 的默认 runtime

  • 操作系统 - Ubuntu
    选择大家熟悉的操作系统

安装 Docker

我们将在 ubuntu 16.04 虚拟机中安装 Docker。因为安装过程需要访问 internet, 所以虚拟机必须能够上网。

Docker 支持几乎所有的 Linux 发行版,也支持 Mac 和 Windows。各操作系统的安装方法可以访问:https://docs.docker.com/install/

Docker 分为开源免费的 CE(Community Edition)版本和收费的 EE(Enterprise Edition)版本。下面我们将按照文档,通过以下步骤在 Ubuntu 16.04 上安装 Docker CE 版本。

Openstack 使用

OpenStack作为基础设施即服务(简称IaaS)资源的通用前端。首要任务是简化云的部署过程并为其带来良好的可扩展性。本文希望通过提供必要的指导信息,帮助大家利用OpenStack前端来设置及管理自己的私有云。

导入虚拟机镜像

如下列出了一下虚拟机镜像,可以在本地下载后通过Openstack界面导入。

https://openstack.redhat.com/Image_resources

也可以参考如下文档自己制作镜像:

https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/OpenStack/page/Creating%20qcow2%20CentOS%20Image%20for%20OpenStack

导入镜像:

点击左侧的镜像 选项卡,可以看到已经导入的镜像,点击创建镜像 按钮创建镜像。

Openstack镜像

填写 镜像名称,镜像源选择—镜像文件,格式选择 QCOW2,勾选 公有 框(这样你上传得镜像其他人也能使用),然后点击创建镜像。

Openstack 安装

OpenStack 是由 Rackspace 和 NASA 共同开发的云计算平台,帮助服务商和企业内部实现类似于 Amazon EC2 和 S3 的云基础架构服务(Infrastructure as a Service, IaaS)。OpenStack 包含两个主要模块:Nova 和 Swift,前者是 NASA 开发的虚拟服务器部署和业务计算模块;后者是Rackspace开发的分布式云存储模块,两者可以一起用,也可以分开单独用。OpenStack 是开源项目,除了有 Rackspace 和 NASA 的大力支持外,后面还有包括 Dell、Citrix、 Cisco、 Canonical 这些重量级公司的贡献和支持,发展速度非常快。

Openstack集群搭建使用5台机器,一台Fuel管理机,一台Controller,一台Compute,两台Storage。这是一个最小化的安装,安装完成后可以对集群进行扩容。

1. 网络环境准备

网络规划:

  • Floating/Public 网络 172.16.200.0/24 in VLAN 100 (untagged on servers) • Floating IP range 172.16.200.130 - 254 # 用于集群公网和虚拟机浮动IP,需要能与外网通信
  • Internal network (private) 192.168.100.0/24 # 用于虚拟机间通信
  • Gateway 192.168.100.1 # 虚拟机的网关地址
  • DNS 8.8.4.4, 8.8.8.8 # DNS地址
  • Management network 192.168.0.0/24 in VLAN 501 # 管理网络
  • Storage network 192.168.1.0/24 in VLAN 502 # 存储网络
  • Administrative network (for Fuel) 10.20.0.0/24 in VLAN 503 # Fuel集群管理网络

Saltstack:Salt模块的扩展

对Salt进行模块化设计就是为了扩展,另外将变量抽象出来放到pillar中也是为了模块可以重用。当你需要配置两个web平台,而这两个平台又有些许不同时你该怎么办?需要重新再写个nginx模块适配新的平台吗?

对于上面问题的回答是否定的,我们无需再重新写一个nginx模块,我们只需要对新的平台传递新的配置文件或者使用同一个模板传递不同的参数。

使用不同的配置文件

当两个平台配置相差比较大时可能传递一个不同的配置文件会更合适,如下:

1
2
3
4
5
6
7
/etc/rsyncd.conf:
file.managed:
- source: salt://rsync/files/etc/{{salt['pillar.get']('rsync_template', 'rsyncd.conf')}}
- template: jinja
- user: root
- group: root
- mode: 644

为不同的节点在pillar中配置不同的rsync_template变量即可。

Saltstack:自动化监控

本节参考了绿肥的《记saltstack和zabbix的一次联姻》,对zabbix添加监控脚本(add_monitors.py)进行部分修改而成,此脚本基于@超大杯摩卡星冰乐 同学的zapi进行更高级别的封装而成,在此表示感谢。

自动化监控的过程如下:

  1. 通过Saltstack部署Zabbix server、Zabbix web、Zabbix api;
  2. 完成安装后需要手动导入Zabbix监控模板;
  3. 通过Saltstack部署服务及Zabbix agent;
  4. Saltstack在安装完服务后通过Salt Mine将服务角色汇报给Salt Master;
  5. Zabbix api拿到各服务角色后添加相应监控到Zabbix server。

Salt Mine用于将Salt Minion的信息存储到Salt Master,供其他Salt Minion使用。

下面以对nginx模块的监控为例讲述整个监控过程,其中Zabbix服务(Zabbix server、Zabbix web、Zabbix api)安装使用/srv/salt/zabbix进行管理,服务部署在admin.grid.mall.com上。Zabbix agent使用/srv/salt/zabbix进行管理。nginx使用/srv/salt/nginx模块进行管理。

安装完nginx和php后定义相应的角色:

Saltstack:代码部署系统搭建

部署系统基于Salt Runner编写,Salt Runner使用salt-run命令执行的命令行工具,可以通过调用Salt API很轻松构建。Salt Runner与Salt的执行模块很像,但是在Salt Master上运行而非Salt Minion上。

配置Salt Master

配置文件(/etc/salt/master.d/publish.conf)如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
svn:
username: 'publish' # 定义svn用户名,用于检出代码
password: '#[email protected]#ht' # svn密码
publish:
master: 'admin.grid.mall.com' # salt master主机名
cwd: '/data1/vhosts' # 代码检出目录
projects:
www.mall.com: # 定义项目名
remote: 'svn://172.16.100.81/www.mall.com' # svn存放路径
target: # 定义代码部署列表 ip::rsync模块
- '172.16.100.21::www_mall_com'
- '172.16.100.22::www_mall_com'
- '172.16.100.23::www_mall_com'

另外还要配置runner的放置目录:runner_dirs: [/srv/salt/_runners],配置完成后要重启Puppet master。

Proudly powered by Hexo and Theme by Hacker
© 2019 ist0ne