wordpress 插件开发插件有没有 做一个信息展示平台 例如家教网 ,技能交换这类的

刚刚阅读在这里,点击刷新
刚刚阅读在这里,点击刷新
本专区为移动开发者打造一流开发环境,提供新闻资讯和全面的技术资源。
使组织和开发人员快速而又轻松地在云上创建、部署和管理应用程序。
了解全新技术,缩短开发周期,帮助您更快地将产品推向市场。
独有的号码认证能力,为接入该能力的App提供一键免密登录的功能。
SIM卡身份认证
传统短信验证
程序员杂志
想在最短时间了解2017年各领域有哪些新技术、新趋势、新工具最值得关注?请别错过本期《程序员》对王健林来说,完成了一次华丽的债转股, 340 亿的还本付息提前清账。对腾讯来说,在收割完线上流量之后,开...
站长热评 建站热点
周热评榜周点击榜
发现互联网营销案例以及最新最酷的营销神器。
中文网站排行
叶根友字体主题下载
| | | | | |
| | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | |
微信扫一扫益学会·译文cali0 是 calico interface,分配的 IP 为 192.168.119.2。cali0 对应 host1 编号 11 的 interface cali5f744ac07f0。
host1 将作为 router 负责转发目的地址为 bbox1 的数据包。
所有发送到 bbox1 的数据都会发给 cali5f744ac07f0,因为 cali5f744ac07f0 与 cali0 是一对 veth pair,bbox1 能够接收到数据。
host1 网络结构如图所示:
接下来我们在 host2 中运行容器 bbox2,也连接到 cal_net1:
docker container run --net cal_net1 --name bbox2 -tid busybox
IP 为 192.168.183.65。
host2 添加了两条路由:
目的地址为 host1 容器 subnet 192.168.119.0/26 的路由。
目的地址为本地 bbox2 容器 192.168.183.65 的路由。
同样的,host1 也自动添加了到 192.168.183.64/26 的路由。
完成了上面这些准备工作,下一节我们将讨论 Calico 网络的连通性。
310001SPJJ
3,659 Views
对于像容器这类平台级别的技术,通常涉及的知识范围会很广,相关的软件,解决方案也会很多,初学者往往容易迷失。
那怎么办呢?
我们可以从生活经验中寻找答案。
当我们去陌生城市旅游想了解一下这个城市一般我们会怎么做?
我想大部分人应该会打开手机看一下这个城市的地图:
城市大概的位置和地理形状是什么?
都由哪几个区或县组成?
主要的交通干道是哪几条?
同样的道理,学习容器技术我们可以先从天上鸟瞰一下:
容器生态系统包含哪些不同层次的技术?
不同技术之间是什么关系?
哪些是核心技术哪些是辅助技术?
首先得对容器技术有个整体认识,之后我们的学习才能够有的放矢,才能够分清轻重缓急,做到心中有数,这样就不容易迷失了。
接下来我会根据自己的经验帮大家规划一条学习路线,一起探索容器生态系统。
学习新技术得到及时反馈是非常重要的,所以我们马上会搭建实验环境,并运行第一个容器,感受什么是容器。
千里之行始于足下,让我们从了解生态系统开始吧。
鸟瞰容器生态系统
一谈到容器,大家都会想到 Docker。
Docker 现在几乎是容器的代名词。确实,是 Docker 将容器技术发扬光大。同时,大家也需要知道围绕 Docker 还有一个生态系统。Docker 是这个生态系统的基石,但完善的生态系统才是保障 Docker 以及容器技术能够真正健康发展的决定因素。
大致来看,容器生态系统包含核心技术、平台技术和支持技术。
下面分别介绍。
容器核心技术
容器核心技术是指能够让 container 在 host 上运行起来的那些技术。
这些技术包括容器规范、容器 runtime、容器管理工具、容器定义工具、Registry 以及 容器 OS,下面分别介绍。
容器不光是 Docker,还有其他容器,比如 CoreOS 的 rkt。为了保证容器生态的健康发展,保证不同容器之间能够兼容,包含 Docker、CoreOS、Google在内的若干公司共同成立了一个叫 Open Container Initiative(OCI) 的组织,其目是制定开放的容器规范。
目前 OCI 发布了两个规范:runtime spec 和 image format spec。
有了这两个规范,不同组织和厂商开发的容器能够在不同的 runtime 上运行。这样就保证了容器的可移植性和互操作性。
runtime 是容器真正运行的地方。runtime 需要跟操作系统 kernel 紧密协作,为容器提供运行环境。
如果大家用过 Java,可以这样来理解 runtime 与容器的关系:
Java 程序就好比是容器,JVM 则好比是 runtime。JVM 为 Java 程序提供运行环境。同样的道理,容器只有在 runtime 中才能运行。
lxc、runc 和 rkt 是目前主流的三种容器 runtime。
lxc 是 Linux 上老牌的容器 runtime。Docker 最初也是用 lxc 作为 runtime。
runc 是 Docker 自己开发的容器 runtime,符合 oci 规范,也是现在 Docker 的默认 runtime。
rkt 是 CoreOS 开发的容器 runtime,符合 oci 规范,因而能够运行 Docker 的容器。
容器管理工具
光有 runtime 还不够,用户得有工具来管理容器啊。容器管理工具对内与 runtime 交互,对外为用户提供 interface,比如 CLI。这就好比除了 JVM,还得提供&java&命令让用户能够启停应用不是。
lxd 是 lxc 对应的管理工具。
runc 的管理工具是 docker engine。docker engine 包含后台 deamon 和 cli 两个部分。我们通常提到 Docker,一般就是指的 docker engine。
rkt 的管理工具是 rkt cli。
容器定义工具
容器定义工具允许用户定义容器的内容和属性,这样容器就能够被保存,共享和重建。
docker image 是 docker 容器的模板,runtime 依据 docker image 创建容器。
dockerfile 是包含若干命令的文本文件,可以通过这些命令创建出 docker image。
ACI (App Container Image) 与 docker image 类似,只不过它是由 CoreOS 开发的 rkt 容器的 image 格式。
容器是通过 image 创建的,需要有一个仓库来统一存放 image,这个仓库就叫做 Registry。
企业可以用 Docker Registry 构建私有的 Registry。
Docker Hub()&是 Docker 为公众提供的托管 Registry,上面有很多现成的 image,为 Docker 用户提供了极大的便利。
Quay.io()是另一个公共托管&Registry,提供与 Docker Hub 类似的服务。
由于有容器 runtime,几乎所有的 Linux、MAC OS 和 Windows 都可以运行容器。但这不并没有妨碍容器 OS 的问世。
容器 OS 是专门运行容器的操作系统。与常规 OS 相比,容器 OS 通常体积更小,启动更快。因为是为容器定制的 OS,通常它们运行容器的效率会更高。
目前已经存在不少容器 OS,CoreOS、atomic 和 ubuntu core 是其中的杰出代表。
下一节继续介绍容器平台技术和容器支持技术。
310001SPJJ
5,361 Views
前面我们讨论了 Neutron 的基本概念,今天我们开始分析 Neutron 的架构。
Neutron 架构
与 OpenStack 的其他服务的设计思路一样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。
Neutron 由如下组件构成:
Neutron Server
对外提供 OpenStack 网络 API,接收请求,并调用 Plugin 处理请求。
处理 Neutron Server 发来的请求,维护 OpenStack 逻辑网络的状态, 并调用 Agent 处理请求。
处理 Plugin 的请求,负责在 network provider 上真正实现各种网络功能。
network provider
提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch 或者其他支持 Neutron 的物理交换机。
Neutron Server,Plugin 和 Agent 之间通过 Messaging Queue 通信和调用。
存放 OpenStack 的网络状态信息,包括 Network, Subnet, Port, Router 等。
Neutron 架构非常灵活,层次较多,其目的是:
为了支持各种现有或者将来会出现的优秀网络技术。
支持分布式部署,获得足够的扩展性。
通常鱼和熊掌不能兼得,虽然获得了这些优势,但这样使得 Neutron 更加复杂,更不容易理解。 后面我们会详细讨论 Neutron 的各个组件,但在这之前,非常有必要先通过一个例子了解这些组件各自的职责以及是如何协同工作。
以创建一个 VLAN100 的 network 为例,假设 network provider 是 linux bridge, 流程如下:
Neutron Server 接收到创建 network 的请求,通过 Message Queue(RabbitMQ)通知已注册的 Linux Bridge Plugin。
Plugin 将要创建的 network 的信息(例如名称、VLAN ID等)保存到数据库中,并通过 Message Queue 通知运行在各节点上的 Agent。
Agent 收到消息后会在节点上的物理网卡(比如 eth2)上创建 VLAN 设备(比如 eth2.100),并创建 bridge (比如 brqXXX) 桥接 VLAN 设备。
关于 linux bridge 如何实现 VLAN 大家可以参考本教程&预备知识-&网络虚拟化&的相关章节。
这里进行几点说明:
plugin 解决的是 What 的问题,即网络要配置成什么样子?而至于如何配置 How 的工作则交由 agent 完成。
plugin,agent 和 network provider 是配套使用的,比如上例中 network provider 是 linux bridge,那么就得使用 linux bridge 的 plungin 和 agent;如果 network provider 换成了 OVS 或者物理交换机,plugin 和 agent 也得替换。
plugin 的一个主要的职责是在数据库中维护 Neutron 网络的状态信息,这就造成一个问题:所有 network provider 的 plugin 都要编写一套非常类似的数据库访问代码。为了解决这个问题,Neutron 在 Havana 版本实现了一个 ML2(Modular Layer 2)plugin,对 plgin 的功能进行抽象和封装。有了 ML2 plugin,各种 network provider 无需开发自己的 plugin,只需要针对 ML2 开发相应的 driver 就可以了,工作量和难度都大大减少。ML2 会在后面详细讨论。
plugin 按照功能分为两类: core plugin 和 service plugin。core plugin 维护 Neutron 的 netowrk, subnet 和 port 相关资源的信息,与 core plugin 对应的 agent 包括 linux bridge, OVS 等; service plugin 提供 routing, firewall, load balance 等服务,也有相应的 agent。后面也会分别详细讨论。
以上是Neutron的逻辑架构,下一节我们讨论 Neutron 的物理部署方案。
310001SPJJ
8,278 Views
Compute Service Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源。
OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是通过 Nova 来实现的。
在上图中可以看到,Nova 处于 Openstak 架构的中心,其他组件都为 Nova 提供支持:
Glance 为 VM 提供 image
Cinder 和 Swift 分别为 VM 提供块存储和对象存储
Neutron 为 VM 提供网络连接
Nova 架构如下
Nova 的架构比较复杂,包含很多组件。
这些组件以子服务(后台 deamon 进程)的形式运行,可以分为以下几类:
接收和响应客户的 API 调用。 除了提供 OpenStack 自己的API,nova-api 还支持 Amazon EC2 API。 也就是说,如果客户以前使用 Amazon EC2,并且用 EC2 的 API 开发了些工具来管理虚机,那么如果现在要换成 OpenStack,这些工具可以无缝迁移到 OpenStack,因为 nova-api 兼容 EC2 API,无需做任何修改。
Compute Core
nova-scheduler
虚机调度服务,负责决定在哪个计算节点上运行虚机
nova-compute
管理虚机的核心服务,通过调用 Hypervisor API 实现虚机生命周期管理
Hypervisor
计算节点上跑的虚拟化管理程序,虚机管理最底层的程序。 不同虚拟化技术提供自己的 Hypervisor。 常用的 Hypervisor 有 KVM,Xen, VMWare 等
nova-conductor
nova-compute 经常需要更新数据库,比如更新虚机的状态。 出于安全性和伸缩性的考虑,nova-compute 并不会直接访问数据库,而是将这个任务委托给 nova-conductor,这个我们在后面会详细讨论。
Console Interface
nova-console
用户可以通过多种方式访问虚机的控制台: nova-novncproxy,基于 Web 浏览器的 VNC 访问 nova-spicehtml5proxy,基于 HTML5 浏览器的 SPICE 访问 nova-xvpnvncproxy,基于 Java 客户端的 VNC 访问
nova-consoleauth
负责对访问虚机控制台请亲提供 Token 认证
提供 x509 证书支持
Nova 会有一些数据需要存放到数据库中,一般使用 MySQL。 数据库安装在控制节点上。 Nova 使用命名为 &nova& 的数据库。
Message Queue
在前面我们了解到 Nova 包含众多的子服务,这些子服务之间需要相互协调和通信。 为解耦各个子服务,Nova 通过 Message Queue 作为子服务的信息中转站。 所以在架构图上我们看到了子服务之间没有直接的连线,它们都通过 Message Queue 联系。
OpenStack 默认是用 RabbitMQ 作为 Message Queue。 MQ 是 OpenStack 的核心基础组件,我们后面也会详细介绍。
下一节我们讨论这些 Nova 组件如何协调工作。
310001SPJJ
9,091 Views
virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。
virbr0 默认分配了一个IP 192.168.122.1,并为连接其上的其他虚拟网卡提供 DHCP 服务。
下面我们演示如何使用 virbr0。
在 virt-manager 打开 VM1 的配置界面,网卡 Source device 选择 &default&,将 VM1 的网卡挂在 virbr0 上。
启动 VM1,brctl show 可以查看到 vnet0 已经挂在了 virbr0 上。
# brctl show
bridge name & & bridge id & & & & & & & STP enabled & & interfaces
br0 & & & & & & decbe & & & no & & & & & & & & & &eth0
virbr0 & & & & &8000.fea & & & yes & & & & & & & & & vnet0
用 virsh 命令确认 vnet 就是 VM1 的虚拟网卡。
# virsh domiflist VM1
Interface &Type & & & Source & & Model & & & MAC
-------------------------------------------------------
vnet0 & & &network & &default & &rtl8139 & & 52:54:00:75:dd:1a
virbr0 使用 dnsmasq 提供 DHCP 服务,可以在宿主机中查看该进程信息
# ps -elf|grep dnsmasq
5 S libvirt+ &2422 & & 1 &0 &80 & 0 - &7054 poll_s 11:26 ? & & & &00:00:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf
在 /var/lib/libvirt/dnsmasq/ 目录下有一个 default.leases 文件,当 VM1 成功获得 DHCP 的 IP 后,可以在该文件中查看到相应的信息
# cat /var/lib/libvirt/dnsmasq/default.leases
52:54:00:75:dd:1a 192.168.122.6 ubuntu *
上面显示 192.168.122.6 已经分配给 MAC 地址为 52:54:00:75:dd:1a 的网卡,这正是 vnet0 的 MAC。之后就可以使用该 IP 访问 VM1 了。
# ssh 192.168.122.6
root@192.168.122.6's password:
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic x86_64)
Last login: Sun Sep &6 01:30:23 2015
root@VM1:~# ifconfig
eth0 & & &Link encap:Ethernet &HWaddr 52:54:00:75:dd:1a
& & & & &inet addr:192.168.122.6 &Bcast:192.168.122.255 &Mask:255.255.255.0
& & & & &inet6 addr: fe80::5054:ff:fe75:dd1a/64 Scope:Link
& & & & &UP BROADCAST RUNNING MULTICAST &MTU:1500 &Metric:1
& & & & &RX packets:61 errors:0 dropped:0 overruns:0 frame:0
& & & & &TX packets:66 errors:0 dropped:0 overruns:0 carrier:0
& & & & &collisions:0 txqueuelen:1000
& & & & &RX bytes: KB) &TX bytes: KB)
Ping一下外网。
root@VM1:~# ping www.baidu.com
PING www.a.shifen.com (180.97.33.107) 56(84) bytes of data.
64 bytes from 180.97.33.107: icmp_seq=1 ttl=52 time=36.9 ms
64 bytes from 180.97.33.107: icmp_seq=2 ttl=52 time=119 ms
64 bytes from 180.97.33.107: icmp_seq=3 ttl=52 time=88.5 ms
64 bytes from 180.97.33.107: icmp_seq=4 ttl=52 time=38.0 ms
64 bytes from 180.97.33.107: icmp_seq=5 ttl=52 time=122 ms
没有问题,可以访问外网,说明 NAT 起作用了。
需要说明的是,使用 NAT 的虚机 VM1 可以访问外网,但外网无法直接访问 VM1。 因为 VM1 发出的网络包源地址并不是 192.168.122.6,而是被 NAT 替换为宿主机的 IP 地址了。
这个与使用 br0 不一样,在 br0 的情况下,VM1 通过自己的 IP 直接与外网通信,不会经过 NAT 地址转换。
下节我们讨论 vlan 在 linux bridge 中的实现
310001SPJJ
伸缩(Scale Up/Down)是指在线增加或减少 Pod 的副本数。
Deployment&nginx-deployment&初始是两个副本。
k8s-node1&和&k8s-node2&上各跑了一个副本。现在修改 nginx.yml,将副本改成 5 个。
再次执行&kubectl apply:
三个新副本被创建并调度到&k8s-node1&和&k8s-node2&上。
出于安全考虑,默认配置下 Kubernetes 不会将 Pod 调度到 Master 节点。如果希望将 k8s-master 也当作 Node 使用,可以执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master-
如果要恢复 Master Only 状态,执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master=&&:NoSchedule
接下来修改配置文件,将副本数减少为 3 个,重新执行&kubectl apply:
可以看到两个副本被删除,最终保留了 3 个副本。
下一节我们学习 Deployment 的 Failover。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
既然要用 YAML 配置文件部署应用,现在就很有必要了解一下 Deployment 的配置格式,其他 Controller(比如 DaemonSet)非常类似。
还是以 nginx-deployment 为例,配置文件如下图所示:
①&apiVersion&是当前配置格式的版本。
②&kind&是要创建的资源类型,这里是&Deployment。
③&metadata&是该资源的元数据,name&是必需的元数据项。
④&spec&部分是该&Deployment&的规格说明。
⑤&replicas&指明副本数量,默认为 1。
⑥&template&定义 Pod 的模板,这是配置文件的重要部分。
⑦&metadata&定义 Pod 的元数据,至少要定义一个 label。label 的 key 和 value 可以任意指定。
⑧&spec&描述 Pod 的规格,此部分定义 Pod 中每一个容器的属性,name&和&image&是必需的。
此 nginx.yml 是一个最简单的 Deployment 配置文件,后面我们学习 Kubernetes 各项功能时会逐步丰富这个文件。
执行&kubectl apply -f nginx.yml:
部署成功。同样地,通过&kubectl get&查看&nginx-deployment&的各种资源:
Deployment、ReplicaSet、Pod 都已经就绪。如果要删除这些资源,执行&kubectl delete deployment nginx-deployment&或者&kubectl delete -f nginx.yml。
下一节讨论 Deployment 的 Scale Up/Down。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
命令 vs 配置文件
Kubernetes 支持两种方式创建资源:
1. 用 kubectl 命令直接创建,比如:
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
在命令行中通过参数指定资源的属性。
2. 通过配置文件和&kubectl apply&创建,要完成前面同样的工作,可执行命令:
kubectl apply -f nginx.yml
nginx.yml 的内容为:
资源的属性写在配置文件中,文件格式为 YAML。
下面对这两种方式进行比较。
基于命令的方式:
基于配置文件的方式:
后面我们都将采用配置文件的方式,大家需要尽快熟悉和掌握。
kubectl apply&不但能够创建 Kubernetes 资源,也能对资源进行更新,非常方便。不过 Kubernets 还提供了几个类似的命令,例如&kubectl create、kubectl replace、kubectl edit&和&kubectl patch。
为避免造成不必要的困扰,我们会尽量只使用&kubectl apply,
此命令已经能够应对超过 90% 的场景,事半功倍。
下节我们来分析一个 Deployment 的配置文件。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
从本章开始,我们将通过实践深入学习 Kubernetes 的各种特性。作为容器编排引擎,最重要也是最基本的功能当然是运行容器化应用,这就是本章的内容。
Deployment
前面我们已经了解到,Kubernetes 通过各种 Controller 来管理 Pod 的生命周期。为了满足不同业务场景,Kubernetes 开发了 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等多种 Controller。我们首先学习最常用的 Deployment。
先从例子开始,运行一个 Deployment:
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
上面的命令将部署包含两个副本的 Deployment&nginx-deployment,容器的 image 为&nginx:1.7.9。
下面详细分析 Kubernetes 都做了些什么工作。
kubectl get deployment&命令可以查看&nginx-deployment&的状态,输出显示两个副本正常运行。
接下来我们用&kubectl describe deployment&了解更详细的信息。
大部分内容都是自解释的,我们重点看最下面部分。这里告诉我们创建了一个 ReplicaSet&nginx-deployment-,Events&是 Deployment 的日志,记录了 ReplicaSet 的启动过程。
通过上面的分析,也验证了 Deployment 通过 ReplicaSet 来管理 Pod 的事实。接着我们将注意力切换到&nginx-deployment-,执行&kubectl describe replicaset:
两个副本已经就绪,用&kubectl describe replicaset&查看详细信息:
Controlled By&指明此 ReplicaSet 是由 Deployment&nginx-deployment&创建。Events&记录了两个副本 Pod 的创建。接着我们来看 Pod,执行&kubectl get pod:
两个副本 Pod 都处于&Running&状态,用&kubectl describe pod&查看更详细的信息:
Controlled By&指明此 Pod 是由 ReplicaSet&nginx-deployment-&创建。Events&记录了 Pod 的启动过程。如果操作失败(比如 image 不存在),也能在这里查看到原因。
总结一下这个过程:
从上图也可以看出,对象的命名方式是:子对象的名字&=&父对象名字&+&随机字符串或数字。
本节我们是通过&kubectl run&创建的 Deployment,下一节学习另一种更常用的方法。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
为了帮助大家更好地理解 Kubernetes 架构,我们部署一个应用来演示各个组件之间是如何协作的。
kubectl run httpd-app --image=httpd --replicas=2
等待一段时间,应用部署完成。
Kubernetes 部署了 deployment&httpd-app,有两个副本 Pod,分别运行在&k8s-node1&和&k8s-node2。
详细讨论整个部署过程。
① kubectl 发送部署请求到 API Server。
② API Server 通知 Controller Manager 创建一个 deployment 资源。
③ Scheduler 执行调度任务,将两个副本 Pod 分发到 k8s-node1 和 k8s-node2。
④ k8s-node1 和 k8s-node2 上的 kubectl 在各自的节点上创建并运行 Pod。
补充两点:
Kubernetes 架构就讨论到这里。从下节开始,我们将通过实践深入学习 Kubernetes 的各种特性。作为容器编排引擎,最重要也是最基本的功能当然是运行容器化应用。下节见。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
上一节我们讨论了 Kubernetes 架构 Master 上运行的服务,本节讨论 Node 节点。
Node 是 Pod 运行的地方,Kubernetes 支持 Docker、rkt 等容器 Runtime。 Node上运行的 Kubernetes 组件有 kubelet、kube-proxy 和 Pod 网络(例如 flannel)。
kubelet 是 Node 的 agent,当 Scheduler 确定在某个 Node 上运行 Pod 后,会将 Pod 的具体配置信息(image、volume 等)发送给该节点的 kubelet,kubelet 根据这些信息创建和运行容器,并向 Master 报告运行状态。
kube-proxy
service 在逻辑上代表了后端的多个 Pod,外界通过 service 访问 Pod。service 接收到的请求是如何转发到 Pod 的呢?这就是 kube-proxy 要完成的工作。
每个 Node 都会运行 kube-proxy 服务,它负责将访问 service 的 TCP/UPD 数据流转发到后端的容器。如果有多个副本,kube-proxy 会实现负载均衡。
Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。
完整的架构图
结合实验环境,我们得到了如下的架构图:
你可能会问:为什么 k8s-master 上也有 kubelet 和 kube-proxy 呢?
这是因为 Master 上也可以运行应用,即 Master 同时也是一个 Node。
几乎所有的 Kubernetes 组件本身也运行在 Pod 里,执行如下命令:
kubectl get pod --all-namespaces -o wide
Kubernetes 的系统组件都被放到&kube-system&namespace 中。这里有一个&kube-dns&组件,它为 Cluster 提供 DNS 服务,我们后面会讨论。kube-dns是在执行&kubeadm init&时(第 ⑤ 步)作为附加组件安装的。
kubelet 是唯一没有以容器形式运行的 Kubernetes 组件,它在 Ubuntu 中通过 Systemd 运行。
为了帮助大家更好地理解 Kubernetes 架构,下节我们将部署一个应用来展示各个组件是如何协作的。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
Kubernetes Cluster 由 Master 和 Node 组成,节点上运行着若干 Kubernetes 服务。
Master 节点
Master 是 Kubernetes Cluster 的大脑,运行着如下 Daemon 服务:kube-apiserver、kube-scheduler、kube-controller-manager、etcd 和 Pod 网络(例如 flannel)。
API Server(kube-apiserver)
API Server 提供 HTTP/HTTPS RESTful API,即 Kubernetes API。API Server 是 Kubernetes Cluster 的前端接口,各种客户端工具(CLI 或 UI)以及 Kubernetes 其他组件可以通过它管理 Cluster 的各种资源。
Scheduler(kube-scheduler)
Scheduler 负责决定将 Pod 放在哪个 Node 上运行。Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。
Controller Manager(kube-controller-manager)
Controller Manager 负责管理 Cluster 各种资源,保证资源处于预期的状态。Controller Manager 由多种 controller 组成,包括 replication controller、endpoints controller、namespace controller、serviceaccounts controller 等。
不同的 controller 管理不同的资源。例如 replication controller 管理 Deployment、StatefulSet、DaemonSet 的生命周期,namespace controller 管理 Namespace 资源。
etcd 负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。
Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。
以上是 Master 上运行的组件,下一节我们讨论 Node。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
上节我们通过 kubeadm 在 k8s-master 上部署了 Kubernetes,本节安装 Pod 网络并添加 k8s-node1 和 k8s-node2,完成集群部署。
安装 Pod 网络
要让 Kubernetes Cluster 能够工作,必须安装 Pod 网络,否则 Pod 之间无法通信。
Kubernetes 支持多种网络方案,这里我们先使用 flannel,后面还会讨论 Canal。
执行如下命令部署 flannel:
kubectl apply -f
添加 k8s-node1 和 k8s-node2
在 k8s-node1 和 k8s-node2 上分别执行如下命令,将其注册到 Cluster 中:
kubeadm join --token d38a01.ccc.56.105:6443
这里的&--token&来自前面&kubeadm init&输出的第 ⑨ 步提示,如果当时没有记录下来可以通过&kubeadm token list&查看。
kubeadm join&执行如下:
根据提示,我们可以通过&kubectl get nodes&查看节点的状态。
目前所有节点都是&NotReady,这是因为每个节点都需要启动若干组件,这些组件都是在 Pod 中运行,需要首先从 google 下载镜像,我们可以通过如下命令查看 Pod 的状态:
kubectl get pod --all-namespaces
Pending、ContainerCreating、ImagePullBackOff&都表明 Pod 没有就绪,Running&才是就绪状态。我们可以通过&kubectl describe pod &Pod Name&&查看 Pod 具体情况,比如:
kubectl describe pod kube-flannel-ds-v0p3x --namespace=kube-system
为了节省篇幅,这里只截取命令输出的最后部分,可以看到在下载 image 时失败,如果网络质量不好,这种情况是很常见的。我们可以耐心等待,因为 Kubernetes 会重试,我们也可以自己手工执行&docker pull&去下载这个镜像。
等待一段时间,image 都成功下载后,所有 Pod 会处于&Running&状态。
这时,所有的节点都已经&Ready,Kubernetes Cluster 创建成功,一切准备就绪。
本章通过 kubeadm 部署了三节点的 Kubernetes 集群,后面章节我们都将在这个实验环境中学习 Kubernetes 的各项技术。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
我们将部署三个节点的 Kubernetes Cluster。
k8s-master 是 Master,k8s-node1 和 k8s-node2 是 Node。
所有节点的操作系统均为 Ubuntu 16.04,当然其他 Linux 也是可以的。
官方安装文档可以参考&
注意:Kubernetes 几乎所有的安装组件和 Docker 镜像都放在 goolge 自己的网站上,这对国内的同学可能是个不小的障碍。建议是:网络障碍都必须想办法克服,不然连 Kubernetes 的门都进不了。
安装 Docker
所有节点都需要安装 Docker。
apt-get update && apt-get install docker.io
安装 kubelet、kubeadm 和 kubectl
在所有节点上安装 kubelet、kubeadm 和 kubectl。
kubelet 运行在 Cluster 所有节点上,负责启动 Pod 和容器。
kubeadm 用于初始化 Cluster。
kubectl 是 Kubernetes 命令行工具。通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。
apt-get update && apt-get install -y apt-transport-httpscurl -s
| apt-key add -cat &&EOF &/etc/apt/sources.list.d/kubernetes.listdeb
kubernetes-xenial mainEOFapt-get updateapt-get install -y kubelet kubeadm kubectl
用 kubeadm 创建 Cluster
完整的官方文档可以参考&
初始化 Master
在 Master 上执行如下命令:
kubeadm init --apiserver-advertise-address 192.168.56.105 --pod-network-cidr=10.244.0.0/16
--apiserver-advertise-address&指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。
--pod-network-cidr&指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对&--pod-network-cidr&有自己的要求,这里设置为&10.244.0.0/16&是因为我们将使用 flannel 网络方案,必须设置成这个 CIDR。在后面的实践中我们会切换到其他网络方案,比如 Canal。
初始化过程如下:
① kubeadm 执行初始化前的检查。
② 生成 token 和证书。
③ 生成 KubeConfig 文件,kubelet 需要这个文件与 Master 通信。
④ 安装 Master 组件,会从 goolge 的 Registry 下载组件的 Docker 镜像,这一步可能会花一些时间,主要取决于网络质量。
⑤ 安装附加组件 kube-proxy 和 kube-dns。
⑥ Kubernetes Master 初始化成功。
⑦ 提示如何配置 kubectl,后面会实践。
⑧ 提示如何安装 Pod 网络,后面会实践。
⑨ 提示如何注册其他节点到 Cluster,后面会实践。
配置 kubectl
kubectl 是管理 Kubernetes Cluster 的命令行工具,前面我们已经在所有的节点安装了 kubectl。Master 初始化完成后需要做一些配置工作,然后 kubectl 就能使用了。
依照&kubeadm init&输出的第 ⑦ 步提示,推荐用 Linux 普通用户执行 kubectl(root 会有一些问题)。
我们为 ubuntu 用户配置 kubectl:
su - ubuntumkdir -p $HOME/.kubesudo
cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo
chown $(id -u):$(id -g) $HOME/.kube/config
为了使用更便捷,启用 kubectl 命令的自动补全功能。
echo &source &(kubectl completion bash)& && ~/.bashrc
这样 ubuntu 用户就可以使用 kubectl 了。
下节我们将安装 Pod 网络并添加 k8s-node1 和 k8s-node2,完成集群部署。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
在实践之前,必须先学习 Kubernetes 的几个重要概念,它们是组成 Kubernetes 集群的基石。
Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。
Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master 运行 Linux 操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个 Master。
Node 的职责是运行容器应用。Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统,可以是物理机或者是虚拟机。
在前面交互式教程中我们创建的 Cluster 只有一个主机&host01,
它既是 Master 也是 Node。
Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。
Kubernetes 引入 Pod 主要基于下面两个目的:
Pods 有两种使用方式:
举个例子。
下面这个 Pod 包含两个容器:一个 File Puller,一个是 Web Server。
File Puller 会定期从外部的 Content Manager 中拉取最新的文件,将其存放在共享的 volume 中。Web Server 从 volume 读取文件,响应 Consumer 的请求。
这两个容器是紧密协作的,它们一起为 Consumer 提供最新的数据;同时它们也通过 volume 共享数据。所以放到一个 Pod 是合适的。
再来看一个反例:是否需要将 Tomcat 和 MySQL 放到一个 Pod 中?
Tomcat 从 MySQL 读取数据,它们之间需要协作,但还不至于需要放到一个 Pod 中一起部署,一起启动,一起停止。同时它们是之间通过 JDBC 交换数据,并不是直接共享存储,所以放到各自的 Pod 中更合适。
Controller&
Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景,Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等,我们逐一讨论。
Deployment&是最常用的 Controller,比如前面在线教程中就是通过创建 Deployment 来部署应用的。Deployment 可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。
ReplicaSet&实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,我们通常不需要直接使用 ReplicaSet。
DaemonSet&用于每个 Node 最多只运行一个 Pod 副本的场景。正如其名称所揭示的,DaemonSet 通常用于运行 daemon。
StatefuleSet&能够保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。
Job&用于运行结束就删除的应用。而其他 Controller 中的 Pod 通常是长期持续运行。
Deployment 可以部署多个副本,每个 Pod 都有自己的 IP,外界如何访问这些副本呢?
通过 Pod 的 IP 吗?
要知道 Pod 很可能会被频繁地销毁和重启,它们的 IP 会发生变化,用 IP 来访问不太现实。
答案是 Service。
Kubernetes Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。
Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。
如果有多个用户或项目组使用同一个 Kubernetes Cluster,如何将他们创建的 Controller、Pod 等资源分开呢?
答案就是 Namespace。
Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。
Kubernetes 默认创建了两个 Namespace。
default&-- 创建资源时如果不指定,将被放到这个 Namespace 中。
kube-system&-- Kubernetes 自己创建的系统资源将放到这个 Namespace 中。
熟悉了 k8s 的这些重要概念,下节开始,我们将搭建自己的 Kubernetes 集群。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
本节带领大家快速体验 k8s 的核心功能:应用部署、访问、Scale Up/Down 以及滚动更新。
执行命令:
kubectl run kubernetes-bootcamp \
--image=docker.io/jocatalin/kubernetes-bootcamp:v1 \
--port=8080
这里我们通过&kubectl run&部署了一个应用,命名为&kubernetes-bootcamp。
Docker 镜像通过&--image&指定。
--port&设置应用对外服务的端口。
这里&deployment&是 Kubernetes 的术语,可以理解为应用。
Kubernetes 还有一个重要术语&Pod。
Pod 是容器的集合,通常会将紧密相关的一组容器放到一个 Pod 中,同一个 Pod 中的所有容器共享 IP 地址和 Port 空间,也就是说它们在一个 network namespace 中。
Pod 是 Kubernetes 调度的最小单位,同一 Pod 中的容器始终被一起调度。
运行&kubectl get pods&查看当前的 Pod。
kubernetes-bootcamp--q9p1t&就是应用的 Pod。
默认情况下,所有 Pod 只能在集群内部访问。对于上面这个例子,要访问应用只能直接访问容器的 8080 端口。为了能够从外部访问应用,我们需要将容器的 8080 端口映射到节点的端口。
执行如下命令:
kubectl expose deployment/kubernetes-bootcamp \
--type=&NodePort& \
--port 8080
执行命令&kubectl get services&可以查看应用被映射到节点的哪个端口。
这里有两个 service,可以将 service 暂时理解为端口映射,后面我们会详细讨论。
kubernetes&是默认的 service,暂时不用考虑。kubernetes-bootcamp&是我们应用的 service,8080 端口已经映射到 host01 的 32320 端口,端口号是随机分配的,可以执行如下命令访问应用:
curl host01:32320
Scale 应用
默认情况下应用只会运行一个副本,可以通过&kubectl get deployments查看副本数。
执行如下命令将副本数增加到 3 个:
kubectl scale deployments/kubernetes-bootcamp --replicas=3
通过&kubectl get pods&也可以看到当前 Pod 也增加到 3 个。
通过&curl&访问应用,可以看到每次请求发送到不同的 Pod,三个副本轮询处理,这样就实现了负载均衡。
要 scale down 也很方便,执行命令:
kubectl scale deployments/kubernetes-bootcamp --replicas=2
其中一个副本被删除了。
当前应用使用的 image 版本为 v1,执行如下命令将其升级到 v2:
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
通过&kubectl get pods&可以观察滚动更新的过程:v1 的 Pod 被逐个删除,同时启动了新的 v2 Pod。更新完成后访问新版本应用。
如果要回退到 v1 版本也很容易,执行&kubectl rollout undo&命令:
kubectl rollout undo deployments/kubernetes-bootcamp
验证版本已经回退到 v1。
至此,我们已经通过官网的交互式教程快速体验了 Kubernetes 的功能和使用方法。教程其余章节将详细讨论 Kubernetes 的架构、典型的部署方法、容器编排能力、网络方案、监控方案,帮助大家全面掌握 Kubernetes 的核心技能。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
据说 Google 的数据中心里运行着超过 20 亿个容器,而且 Google 十年前就开始使用容器技术。
最初,Google 开发了一个叫 Borg 的系统(现在命令为 Omega)来调度如此庞大数量的容器和工作负载。在积累了这么多年的经验后,Google 决定重写这个容器管理系统,并将其贡献到开源社区,让全世界都能受益。
这个项目就是 Kubernetes。简单的讲,Kubernetes 是 Google Omega 的开源版本。
从 2014 年第一个版本发布以来,Kubernetes 迅速获得开源社区的追捧,包括 Red Hat、VMware、Canonical 在内的很多有影响力的公司加入到开发和推广的阵营。目前 Kubernetes 已经成为发展最快、市场占有率最高的容器编排引擎产品。
Kubernetes 一直在快速地开发和迭代。本章我们将以 v1.7 和 v1.8 为基础学习 Kubernetes。我们会讨论 Kubernetes 重要的概念和架构,学习 Kubernetes 如何编排容器,包括优化资源利用、高可用、滚动更新、网络插件、服务发现、监控、数据管理、日志管理等。
下面就让我们开始 Kubernetes 的探险之旅。
按照一贯的学习思路,我们会在最短时间内搭建起一个可用系统,这样就能够尽快建立起对学习对象的感性认识。先把玩起来,快速了解基本概念、功能和使用场景。
越是门槛高的知识,就越需要有这么一个最小可用系统。如果直接上来就学习理论知识和概念,很容易从入门到放弃。
当然,要搭建这么一个可运行的系统通常也不会太容易,不过很幸运,Kubernetes 官网已经为大家准备好了现成的最小可用系统。
kubernetes.io 开发了一个交互式教程,通过 Web 浏览器就能使用预先部署好的一个 kubernetes 集群,快速体验 kubernetes 的功能和应用场景,下面我就带着大家去玩一下。
页面左边就能看到教程菜单:
教程会指引大家完成创建 kubernetes 集群、部署应用、访问应用、扩展应用、更新应用等最常见的使用场景,迅速建立感性认识。
创建 Kubernetes 集群
点击教程菜单&1. Create a Cluster&-&&Interactive Tutorial - Creating a Cluster
显示操作界面。
左边部分是操作说明,右边是 Terminal,命令终端窗口。
按照操作说明,我们在 Terminal 中执行&minikube start,然后执行&kubectl get nodes,这样就创建好了一个单节点的 kubernetes 集群。
集群的唯一节点为&host01,需要注意的是当前执行命令的地方并不是&host01。我们是在通过 Kubernetes 的命令行工具&kubectl&远程管理集群。
执行&kubectl cluster-info&查看集群信息:
heapster、kubernetes-dashboard&都是集群中运行的服务。
注:为节省篇幅,在后面的演示中,我将简化操作步骤,详细的说明和完整步骤请参考官网在线文档。
集群创建好了,下一节我将带领大家快速体验 Kubernetes 的核心功能。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
这是一个系统学习 Kubernetes 的教程,有下面两个特点:
为什么要学 Kubernetes ?
因为&Kubernetes 太热门了。
2017 年 9 月,Mesosphere 宣布 支持 Kubernetes;10 月,Docker 宣布将在新版本中加入对 Kubernetes 的原生支持。至此,容器编排引擎领域的三足鼎立时代结束,Kubernetes 赢得全面胜利。
其实早在 2015 年 5 月,Kubernetes 在 Google 上的的搜索热度就已经超过了 Mesos 和 Docker Swarm,从那儿之后更是一路飙升,将对手甩开了十几条街。
目前,AWS、Azure、Google、阿里云、腾讯云等主流公有云提供的是基于 Kubernetes 的容器服务;Rancher、CoreOS、IBM、Mirantis、Oracle、Red Hat、VMWare 等无数厂商也在大力研发和推广基于 Kubernetes 的容器 CaaS 或 PaaS 产品。可以说,Kubernetes 是当前容器行业最炙手可热的明星。
每一轮新技术的兴起,无论对公司还是个人既是机会也是挑战。如果这项新技术未来必将成为主流,那么作为 IT 从业者,正确的做法就&尽快掌握。因为:
机会讲过了,咱们再来看看挑战。
新技术往往意味着技术上的突破和创新,会有不少新的概念和方法。
对于 Kubernetes 这项平台级技术,覆盖的技术范围非常广,包括了计算、网络、存储、高可用、监控、日志管理等多个方面,要掌握这些新技术对 IT 老兵尚有不小难度,更别说新人了。
谁需要学 Kubernetes ?
这套教程的目标读者包括:
IT 实施和运维工程师
越来越多的应用将以容器的方式在开发、测试和生产环境中运行。掌握基于 Kubernetes 的容器平台运维能力将成为实施和运维工程师的核心竞争力。
软件开发人员
基于容器的微服务架构(Microservice Architecture)会逐渐成为开发应用系统的主流。而 Kubernetes 将是运行微服务应用的理想平台,市场将需要大量具备 Kubernetes 技能的应用程序开发人员。
如何学习 Kubernetes ?
这个教程将通过大量实例系统讲解 Kubernetes 的核心技术。大家一定要跟着教程实践,这样才能把知识变成自己的。如果仅仅是看一遍最多能记住几个概念,在工作中是用不起来的。
理论一定要联系实际
CloudMan 希望通过这个教程降低大家的学习曲线,真正掌握 Kubernetes。&
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
stack 将应用所包含的 service,依赖的 secret、voluem 等资源,以及它们之间的关系定义在一个 YAML 文件中。相比较手工执行命令或是脚本,stack 有明显的优势。
YAML 描述的是 What,是 stack 最终要达到的状态。
比如 service 有几个副本?使用哪个 image?映射的端口是什么?而脚本则是描述如何执行命令来达到这个状态,也就是 How。显而易见,What 更直观,也更容易理解。至于如何将 What 翻译成 How,这就是 Docker swarm 的任务了,用户只需要告诉 Docker 想达到什么效果。
重复部署应用变得非常容易。
部署应用所需要的一切信息都已经写在 YAML 中,要部署应用只需一条命令 docker stack deploy。stack 的这种自包含特性使得在不同的 Docker 环境中部署应用变得极其简单。在开发、测试和生成环境中部署可以完全采用同一份 YAML,而且每次部署的结果都是一致的。
可以像管理代码一样管理部署。
YAML 本质上将应用的部署代码化了,任何对应用部署环境的修改都可以通过修改 YAML 来实现。可以将 YAML 纳入到版本控制系统中进行管理,任何对 YAML 的修改都会被记录和跟踪,甚至可以像评审代码一样对 YAML 执行 code review。应用部署不再是一个黑盒子,也不再是经验丰富的工程师专有的技能,所以的细节都在 YAML 中,清晰可见。
Docker Swarm 的主题就讨论到此,下一节我们开始学习 Kubernetes。&
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
1,036 Views
定义好了 stack YAML 文件,就可以通过&docker stack deploy&命令部署应用。
Docker 会按照 YAML 的内容来创建各种资源。为了不重名,所有资源都会加上 stack 名称作为前缀,我们这里是 wpstack_*。
部署完成后可以通过相关命令查看各种资源的状态。
如果想更新 stack 的某些属性,直接修改 YAML 文件,然后重新部署。比如将 WordPress 的端口由 8000 改为 8888。
再次执行 docker stack deploy 命令。
stack 更新成功。查看 service wpstack_wordpress 的信息,确认端口已经更新为 8888:
为了更新端口,swarm 启动了一个新的 wpstack_wordpress容器,之前的容器已经被 shutdown。
要删除 stack 也很简单:
docker stack rm 会将 stack 相关的所以资源清除干净。
下一节我们总结一下 stack 的优点。&
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
1,033 Views
什么是 stack ?
在回答这个问题之前我们先回忆一下前面部署 WordPress 应用的过程:
首先创建 secret。
然后创建 MySQL service,这是 WordPress 依赖的服务。
最后创建 WordPress service。
也就是说,这个应用包含了两个 service:MySQL 和 WordPress,它们之间有明确的依赖关系,必须先启动 MySQL。
为了保证这个依赖关系,我们控制了 docker secret 和 docker service 命令的执行顺序,只不过这个过程是手工完成的。
假如我们需要频繁地在不同环境中部署 WordPress 应用,如果每次都手工执行效率就太低了,而且容易出错。这是自动化的一个好机会,首先我们能想到的就是把这个过程写成脚本,大概内容如下:
稍微复杂一点的是第三步,通过 if 判断 MySQL service 是否运行,如果是,则运行 WordPress service,否则通过 while 继续等待,直到 MySQL 运行。
这个脚本大体上能够工作,实现了自动化,但有两个缺点:
目前只有两个 service,还比较简单。现在的应用通常都包含多个 service,特别是采用 microservices 架构的应用,几十个 service 是很正常的。用 shell 脚本启动和管理如此多的 service 将是一件非常有挑战的任务。
用 while 和 if 维护 service 之间的依赖关系也是很有挑战的,容易出错。而且如何判断 service 正常运行也不是件容易的事,脚本中只简单检查了 service 是否存在,并没有考虑 service 的实际运行状态。
我们希望有一种更高效和可靠的方法来部署基于 service 的应用,这就是 stack。
stack 包含一系列 service,这些 service 组成了应用。stack 通过一个 YAML 文件定义每个 service,并描述 service 使用的资源和各种依赖。
WordPress 的 stack 版本
如果将前面 WordPress 用 stack 来定义,YAML 文件可以是这样:
YAML 是一种阅读性很强的文本格式,上面这个 stack 中定义了三种资源:service、secret 和 volume。
① services 定义了两个 service:db 和 wordpress。
② secrets 定义了两个 secret:db_password 和 db_root_password,在 service db 和 wordpress 的定义中引用了这两个 secret。
③ volumes 定义了一个 volume:db_data,service db 使用了此 volume。
④ wordpress 通过 depends_on 指定自己依赖 db 这个 service。Docker 会保证当 db 正常运行后再启动 wordpress。
可以在 YAML 中定义的元素远远不止这里看到的这几个,完整列表和使用方法可参考文档
stack 的 YAML 有了,下一节我们学习 stack 的相关操作。&
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
1,068 Views
在下面的例子中,我们会部署一个 WordPress 应用,WordPress 是流行的开源博客系统。
我们将创建一个 MySQL service,将密码保存到 secret 中。我们还会创建一个 WordPress service,它将使用 secret 连接 MySQL。这个例子将展示如何用 secret 避免在 image 中存放敏感信息,或者在命令行中直接传递敏感数据。
实验步骤如下:
创建 secret
创建 secret 存放 MySQL 的管理员密码。
openssl rand -base64 20 | docker secret create mysql_root_password -
密码是由 openssl 生成的随机字符串。
注意 ag7injh6juonwl09lq8st36o8 是新创建的 service 的 ID,而非 service 的内容。
上面这种方式是从标准输入读取 secret 的内容,也可以指定从文件中读取,例如:
openssl rand -base64 20 & password.txtdocker secret create my_password ./password.txt
一般情况下,应用不会直接用 root 密码访问 MySQL。我们会创建一个单独的用户 workpress,密码存放到 secret mysql_password中。
openssl rand -base64 20 | docker secret create mysql_password -
创建自定义的 overlay 网络
MySQL 通过 overlay 网络 mysql_private 与 WordPress 通信,不需要将 MySQL service 暴露给外部网络和其他容器。
docker network create -d overlay mysql_private
创建 MySQL service
命令如下:
docker service create \
--name mysql \
--network mysql_private \
--secret source=mysql_root_password,target=mysql_root_password \
--secret source=mysql_password,target=mysql_password \
-e MYSQL_ROOT_PASSWORD_FILE=&/run/secrets/mysql_root_password& \
-e MYSQL_PASSWORD_FILE=&/run/secrets/mysql_password& \
-e MYSQL_USER=&wordpress& \
-e MYSQL_DATABASE=&wordpress& \
mysql:latest
MYSQL_DATABASE 指明创建数据库 wordpress。
MYSQL_USER 和 MYSQL_PASSWORD_FILE 指明创建数据库用户 workpress,密码从 secret mysql_password 中读取。
有关 mysql 镜像环境变量更详细的使用方法可参考
创建 WordPress service
MySQL service 已就绪,现在创建 WordPress service。命令如下:
docker service create \
--name wordpress \
--network mysql_private \
--publish 30000:80 \
--secret source=mysql_password,target=wp_db_password \
-e WORDPRESS_DB_HOST=&mysql:3306& \
-e WORDPRESS_DB_NAME=&wordpress& \
-e WORDPRESS_DB_USER=&wordpress& \
-e WORDPRESS_DB_PASSWORD_FILE=&/run/secrets/wp_db_password& \
wordpress:latest
WORDPRESS_DB_HOST 指明 MySQL service 地址 mysql:3306,这里用到了 DNS。
WORDPRESS_DB_NAME 指明 WordPress 的数据库为 wordpress,与前面 MYSQL_DATABASE 一致。
WORDPRESS_DB_USER 指明连接 WordPress 数据库的用户为 wordpress,与前面 MYSQL_USER 一致。
WORDPRESS_DB_PASSWORD_FILE 指明数据库的用户 wordpress 的密码,从 secret mysql_password 中获取。
有关 wordpress 镜像环境变量更详细的使用方法可参考
验证 WordPress
能正常显示初始化界面,表明 WordPress 已经连接到 MySQL,部署成功。
Secret 就讨论到这里,下一节我们学习 Stack。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
1,125 Views
我们可以用 secret 管理任何敏感数据。这些敏感数据是容器在运行时需要的,同时我们不又想将这些数据保存到镜像中。
secret 可用于管理:
用户名和密码。
TLS 证书。
SSH 秘钥。
其他小于 500 KB 的数据。
secret 只能在 swarm service 中使用。普通容器想使用 secret,可以将其包装成副本数为 1 的 service。
这里我们再举一个使用 secret 的典型场景。
数据中心有三套 swarm 环境,分别用于开发、测试和生产。对于同一个应用,在不同的环境中使用不同的用户名密码。我们可以在三个环境中分别创建 secret,不过使用相同的名字,比如 username 和 password。应用部署时只需要指定 secret 名字,这样我们就可以用同一套脚本在不同的环境中部署应用了。
除了敏感数据,secret 当然也可以用于非敏感数据,比如配置文件。不过目前新版本的 Docker 提供了 config 子命令来管理不需要加密的数据。config 与 secret 命令的使用方法完全一致。
Secret 的安全性
当在 swarm 中创建 secret 时,Docker 通过 TLS 连接将加密后的 secret 发送给所以的 manager 节点。
secret 创建后,即使是 swarm manager 也无法查看 secret 的明文数据,只能通过 docker secret inspect 查看 secret 的一般信息。
只有当 secret 被指定的 service 使用是,Docker 才会将解密后的 secret 以文件的形式 mount 到容器中,默认的路径为/run/secrets/&secret_name&。例如在前面 MySQL 的例子中,我们可以在容器中查看 secret。
当容器停止运行,Docker 会 unmount secret,并从节点上清除。
下一节我们再通过一个更加综合例子加深对 Secret 的理解。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
1,141 Views
我们经常要向容器传递敏感信息,最常见的莫过于密码了。比如:
docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
在启动 MySQL 容器时我们通过环境变量 MYSQL_ROOT_PASSWORD 设置了 MySQL 的管理员密码。不过密码是以明文的形式写在 docker run 命令中,有潜在的安全隐患。
为了解决这个问题,docker swarm 提供了 secret 机制,允许将敏感信息加密后保存到 secret 中,用户可以指定哪些容器可以使用此 secret。
如果使用 secret 启动 MySQL 容器,方法是:
在 swarm manager 中创建 secret my_secret_data,将密码保存其中。
echo &my-secret-pw& | docker secret create my_secret_data -
启动 MySQL service,并指定使用 secret my_secret_data。
docker service create \
--name mysql \
--secret source=my_secret_data,target=mysql_root_password \
-e MYSQL_ROOT_PASSWORD_FILE=&/run/secrets/mysql_root_password& \
mysql:latest
① source 指定容器使用 secret 后,secret 会被解密并存放到容器的文件系统中,默认位置为 /run/secrets/&secret_name&。--secret&source=my_secret_data,target=mysql_root_password 的作用就是指定使用 secret my_secret_data,然后把器解密后的内容保存到容器 /run/secrets/mysql_root_password 文件中,文件名称 mysql_root_password 由 target 指定。
② 环境变量 MYSQL_ROOT_PASSWORD_FILE 指定从 /run/secrets/mysql_root_password 中读取并设置 MySQL 的管理员密码。
这里大家可能有这么两个疑问:
问:在第一步创建 secret 时,不也是使用了明文吗?这跟在环境变量中直接指定密码有什么不同呢?
答:在我们的例子中创建 secret 和使用 secret 是分开完成的,其好处是将密码和容器解耦合。secret 可以由专人(比如管理员)创建,而运行容器的用户只需使用 secret 而不需要知道 secret 的内容。也就是说,例子中的这两个步骤可以由不同的人在不同的时间完成。
问:secret 是以文件的形式 mount 到容器中,容器怎么知道去哪里读取 secret 呢?
答:这需要 image 的支持。如果 image 希望它部署出来的容器能够从 secret 中读取数据,那么此 image 就应该提供一种方式,让用户能够指定 secret 的位置。最常用的方法就是通过环境变量,Docker 的很多官方 image 都是采用这种方式。比如 MySQL 镜像同时提供了 MYSQL_ROOT_PASSWORD 和 MYSQL_ROOT_PASSWORD_FILE 两个环境变量。用户可以用 MYSQL_ROOT_PASSWORD 显示地设置管理员密码,也可以通过 MYSQL_ROOT_PASSWORD_FILE 指定 secret 路径。
下一节我们继续讨论 Secret。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
310001SPJJ
1,417 Views
容器状态是 UP 的,应用就是健康的吗?
还真不一定!
Docker 只能从容器启动进程的返回代码判断其状态,而对于容器内部应用的运行情况基本没有了解。
执行 docker run 命令时,通常会根据 Dockerfile 中的 CMD 或 ENTRYPOINT 启动一个进程,这个进程的状态就是 docker ps STATUS 列显示容器的状态。
命令显示:
有的容器正在运行,状态为 UP。
有的容器已经正常停止了,状态是 Exited (0)。
有的则因发生故障停止了,退出代码为非 0,例如 Exited (137)、Exited (1) 等。
即使容器状态是 UP,也不能保证应用没有问题。web server 虽然没有崩溃,但如果总是返回 HTTP 500 - Internal Server Error ,对应用来说这就是很严重的故障。
如何从应用的业务层面检查容器的状态呢? 答案是:Health Check。
Docker 支持的 Health Check 可以是任何一个单独的命令,Docker 会在容器中执行该命令,如果返回 0,容器被认为是 healthy,如果返回 1,则为 unhealthy。
对于提供 HTTP 服务接口的应用,常用的 Health Check 是通过 curl 检查 HTTP 状态码,比如:
curl --fail
如果 curl 命令检测到任何一个错误的 HTTP 状态码,则返回 1,Health Check 失败。
下面我们通过例子来演示 Health Check 在 swarm 中的应用。
docker service create --name my_db \
--health-cmd &curl --fail
|| exit 1& \
--health-cmd Health Check 的命令,还有几个相关的参数:
--timeout 命令超时的时间,默认 30s。
--interval 命令执行的间隔时间,默认 30s。
--retries 命令失败重试的次数,默认为 3,如果 3 次都失败了则会将容器标记为 unhealthy。swarm 会销毁并重建 unhealthy 的副本。
通过 docker ps 可以查看到容器的状态为 healthy:
下面模拟一个 unhealthy 的场景,curl 指向一个不存在的 url。
docker service create --name my_db \
--health-cmd &curl --fail
|| exit 1& \
副本被 shutdown 了,可以到 swarm-worker1 用 docker inspect 查看具体原因。
root@swarm-worker1:~# docker inspect my_db.1.saebvmn7aql2l2n4kgp6s1lui
容器被标记为 unhealthy,其原因是 curl 连续三次返回 404 错误。
Docker 默认只能通过容器进程的返回码判断容器的状态,Health Check 则能够从业务角度判断应用是否发生故障,是否需要重启。
Health Check 就讨论到这里,下一节我们学习如何在容器中使用密码,私钥这类敏感数据。
1.《每天5分钟玩转Docker容器技术》
2.《每天5分钟玩转OpenStack》
Jump to page}

我要回帖

更多关于 wordpress 插件开发 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信