Docker 管理平台(Rancher)

环境信息
3台服务器
192.168.2.110 rancher
192.168.2.112 docker0
192.168.2.113 docker1

软件版本
操作系统:centos7.3
rancher:v1.6.11
在rancher上安装rancher

概念:http://rancher.com/docs/rancher/v1.6/zh/

来自rancher官方文档
Rancher是一个开源的企业级容器管理平台。通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台。Rancher提供了在生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台。

Rancher由以下四个部分组成:

基础设施编排
Rancher可以使用任何公有云或者私有云的Linux主机资源。Linux主机可以是虚拟机,也可以是物理机。Rancher仅需要主机有CPU,内存,本地磁盘和网络资源。从Rancher的角度来说,一台云厂商提供的云主机和一台自己的物理机是一样的。

Rancher为运行容器化的应用实现了一层灵活的基础设施服务。Rancher的基础设施服务包括网络, 存储, 负载均衡, DNS和安全模块。Rancher的基础设施服务也是通过容器部署的,所以同样Rancher的基础设施服务可以运行在任何Linux主机上。

容器编排与调度
很多用户都会选择使用容器编排调度框架来运行容器化应用。Rancher包含了当前全部主流的编排调度引擎,例如Docker Swarm, Kubernetes, 和Mesos。同一个用户可以创建Swarm或者Kubernetes集群。并且可以使用原生的Swarm或者Kubernetes工具管理应用。

除了Swarm,Kubernetes和Mesos之外,Rancher还支持自己的Cattle容器编排调度引擎。Cattle被广泛用于编排Rancher自己的基础设施服务以及用于Swarm集群,Kubernetes集群和Mesos集群的配置,管理与升级。

应用商店
Rancher的用户可以在应用商店里一键部署由多个容器组成的应用。用户可以管理这个部署的应用,并且可以在这个应用有新的可用版本时进行自动化的升级。Rancher提供了一个由Rancher社区维护的应用商店,其中包括了一系列的流行应用。Rancher的用户也可以创建自己的私有应用商店。

企业级权限管理
Rancher支持灵活的插件式的用户认证。支持Active Directory,LDAP, Github等 认证方式。 Rancher支持在环境级别的基于角色的访问控制 (RBAC),可以通过角色来配置某个用户或者用户组对开发环境或者生产环境的访问权限。

rancher本身也是个master/agent的架构模式,在server端安装的是rancher-server,被rancher纳管的机器,安装rancher-agent等其他rancher组件。

单节点安装

container-0上
通过容器的方式安装

1
docker run -d --restart=unless-stopped -p 8080:8080 rancher/server

HA方式安装

组件分配
vip 192.168.2.120
192.168.2.110 rancher-server、nginx、mariadb、keepalived

192.168.2.112 rancher-server、nginx、mariadb、keepalived

192.168.2.113 rancher-server、nginx、mariadb、keepalived

建议采用3台host
3台host上面都部署keepalive+rancher+nginx+mysql
nginx做反向代理
keepalive用于管理vip落到健康的节点
mysql做galera集群,保证3个节点数据库一致

配置环境

绑定hosts

1
2
scp /etc/hosts 192.168.2.112:/etc/hosts  
scp /etc/hosts 192.168.2.113:/etc/hosts

在三台服务器上安装nginx和keepalived

1
yum install nginx keepalived -y

三台服务器启动nginx

1
systemctl start nginx && systemctl enable nginx  

编写测试网页
每个host上都不同,以此来验证。

1
2
3
[root@container-0 ~]# echo "container-0" > /usr/share/nginx/html/index.html
[root@container-1 ~]# echo "container-1" > /usr/share/nginx/html/index.html
[root@container-2 ~]# echo "container-2" > /usr/share/nginx/html/index.html

重启nginx

1
systemctl restart nginx

验证

配置keepalived

修改配置前先备份配置文件

1
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

编辑keepalived配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
! Configuration File for keepalived
vrrp_script check_running {
script "/opt/check.sh"
interval 10 #执行的间隔时间
weight -20 # script执行失败vrrp_instance的优先级会减少20,比如master为100 slave为90,master故障后优先级掉到80,slave比master高,则vip到slave,若,master恢复优先级又会大于backup节点mater重新接管
}

vrrp_instance VI_1 {
state MASTER #设置为主服务器
interface ens3 #vip放置的网卡
virtual_router_id 51 #主、备必须一样 ,这样加入一个集群
priority 100 #(主、备机取不同的优先级,主机值较大,备份机值较小,值越大优先级越高)
advert_int 1
authentication {
auth_type PASS #VRRP认证方式,主备必须一致
auth_pass 1111 ##(密码)
}
virtual_ipaddress {
192.168.2.120 #vip地址
}
track_script { #执行服务检查
check_running
}
}

scp一份到另外两个备节点

1
2
scp /etc/keepalived/keepalived.conf container-1:/etc/keepalived/keepalived.conf
scp /etc/keepalived/keepalived.conf container-2:/etc/keepalived/keepalived.conf

两个备节点修改下配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
! Configuration File for keepalived
vrrp_script check_running {
script "/opt/check.sh" #检查脚本
interval 10
weight -20
}

vrrp_instance VI_1 {
state BACKUP #节点类型为backup
interface ens3
virtual_router_id 51
priority 90 #优先级要比master节点低
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.2.120
}
track_script {
check_running
}
}

编写进程检测脚本为防止脑裂。(container-1和cotainer-2上的脚本需要修改ping那hostname,别ping自己。)
vim /opt/check.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
function check_process {
ps -ef |grep nginx|grep -v grep &>/dev/null
value=`echo $?`
if [ $value -ne 0 ];then
pkill keepalived
fi
}
#如果ping集群另外机器和网关都ping不通,则本身网络出问题,为防止脑裂,自杀。
function check_network {
ping container-1 -c 5 &>/dev/null
value1=`echo $?`
ping container-2 -c 5 &>/dev/null
value2=`echo $?`
ping 192.168.2.1 -c 5 &>/dev/null
value3=`echo $?`
if [ $value1 -ne 0 -a $value2 -ne 0 -a $value3 -ne 0 ];then
pkill keepalived
fi
}
main() {
check_process
check_network
}
main

添加执行权限

1
chmod a+x /opt/check.sh   

脚本scp到container-1、container-2的/opt/目录,添加执行权限

1
2
3
4
scp /opt/check.sh container-1:/opt/check.sh
scp /opt/check.sh container-2:/opt/check.sh
ssh container-1 "chmod a+x /opt/check.sh"
ssh container-2 "chmod a+x /opt/check.sh"

container-1和container-2启动keepalived

1
systemctl start keepalived && systemctl enable keepalived

验证keepalived
验证nginx进程被kill掉时 vip迁移
目前vip在master节点ens3上

将master节点的nginx kill掉

去把container-2的nginx kill掉

验证网络出问题时vip的迁移动
将container-0的 ens3网卡关闭

1
ifdown ens3

配置mariadb galera集群

三个节点操作
配置repo文件
vim /etc/yum.repo/mariadb.repo

1
2
3
4
5
[mariadb]
name = MariaDB
baseurl = https://mirrors.ustc.edu.cn/mariadb/yum/10.2/centos7-amd64
gpgkey=https://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck=1
1
yum install MariaDB-server MariaDB-client galera
1
systemctl start mariadb

一些初始化安全配置

1
/usr/bin/mysql_secure_installation  

关闭数据库

1
systemctl stop mariadb

修改container-0上的/etc/my.cnf.d/server.cnf文件如下

1
2
3
4
5
6
7
8
9
[galera]
wsrep_provider = /usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address = "gcomm://192.168.2.110,192.168.2.112,192.168.2.113"
wsrep_node_name = container-0
wsrep_node_address=192.168.2.110
wsrep_on=ON
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2

将此文件复制到container-1、container-2,注意要把 wsrep_node_name 和 wsrep_node_address 改成相应节点的 hostname 和 ip。

查看是否启用galera插件

连接mariadb,查看是否启用galera插件

配置nginx反向代理

三个节点
备份配置文件

1
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
include /etc/nginx/conf.d/*.conf;

events {
worker_connections 1024;
}

创建rancher配置文件
vim /etc/nginx/conf.d/rancher.conf
http {
upstream rancher {
server 192.168.2.110:8080;
server 192.168.2.112:8080;
server 192.168.2.113:8080;
}
server {
listen 80;
server_name 192.168.2.120;

location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://rancher;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 900s;
}
}
}

同步这两个配置文件到另外两个主机
重启nginx

1
systemctl restart nginx  

三个节点安装rancher-server
在mariadb上创建库并授权用户

1
2
3
4
CREATE DATABASE IF NOT EXISTS cattle COLLATE = 'utf8_general_ci' CHARACTER SET = 'utf8';
GRANT ALL ON cattle.* TO 'cattle'@'%' IDENTIFIED BY 'cattle';
GRANT ALL ON cattle.* TO 'cattle'@'localhost' IDENTIFIED BY 'cattle';

使用外部数据库
在三个host上执行

1
docker run -d --restart=unless-stopped -p 8080:8080  -p 9345:9345 rancher/server --db-host xxxx --db-user cattle --db-pass cattle --db-name cattle --advertise-address xxxx

–advertise-address 为当前主机ip
–db-host 指定MySQL服务器的连接地址(写本机ip)
–db-port 连接端口
–db-user 连接用户
–db-pass 连接密码
–db-name 连接库名

非HA
打开浏览器访问http://localhost:8080

HA情况
打开浏览器访问http://192.168.2.120
在系统管理–>高可用里面可以看见集群

测试高可用
将container-0关机
访问192.168.2.120 正常显示
创建帐号
系统配置—->访问控制—->本地帐号验证

以新帐号登录,并选择中文

添加主机进rancher管理
将另外两台host给rancher管理,需要安装rancher-agent

复制图上第5步的命令
在192.168.2.112上执行

1
sudo docker run -e CATTLE_AGENT_IP="192.168.2.112"  --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.7 http://192.168.2.110:8080/v1/scripts/282E41C46DCA4A2041AA:1483142400000:CPSeNWQ19B9bCfFAULmsX4TKY

在rancher上可以看见
刚刚添加的主机已经进来了

在主机上查看发现rancher会在host上起这些容器

1
2
3
4
5
6
7
8
9
r-network-services-metadata-dns-1-ffdc1af6
r-ipsec-ipsec-router-1-eed9ad34
r-scheduler-scheduler-1-9a4c9847
r-ipsec-cni-driver-1-e5fd917d
r-healthcheck-healthcheck-1-0363e64b
r-ipsec-ipsec-1-f3612834
r-network-services-network-manager-1-9d604f7e
r-network-services-metadata-1-198285ae
rancher-agent

其中
rancher-net:rancher网络的核心,它的作用是用strongSwan 和 charon创建IPSec网络;
rancher-scheduler:负责容器的调度,选择合适的宿主机;
rancer-dns:负责容器的主机名和ip的映射;
rancher-metadata:为容器提供元数据的管理;
rancher-healthcheck: 为容器提供健康状态检查,原理是通过haproxy进行检查,只有使用了rancher的托管网络才的容器才能被检查,其他网络检测不到;

基本使用

点进host名字
可以查看这个host的硬件信息和资源负载情况

按上面方法添加第二个host
对容器的基本操作

启动、停止、查看日志、执行命令

构建单主机容器应用

玩个简单的添加个http的container
在对应的host下点击添加容器

输入应用的基本信息

可以看见httpd容器已经起来了

访问ip为宿主机的ip地址

构建多主机的容器集群应用

两种方式
一种是通过rancher本身自带的应用商店
另外一种通过自己编写的docker-compose或rancher-compose,来进行应用编排

方式一
通过应用商店构建grafana
在应用商店搜索grafana

查看详情里面选择版本和设置密码

预览这可以看见对应的docker-compose和rancher-compose

点击部署后
默认会生成1个容器

访问
进行容器伸缩
添加负载均衡器

配置负载均衡器


访问负载均衡器的地址

容器的伸缩
点击容器名

进容器的管理页,通过修改容器数量进行增减

这样就做成了一个简单的高可用

方式二通过docker-compose进行构建应用
用以下docker-compose构建个WordPress
WordPress主要由三部分构建web Server+php+database
这里是WordPress镜像里面本身包含了php和apache,只要安装WordPress和mysql就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: '2'
services:
db1:
image: mysql:5.7
volumes:
- /var/lib/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress

wordpress:
image: wordpress:latest
depends_on:
- db1
ports:
- 8000:80
environment:
- WORDPRESS_DB_HOST=db1
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress


构建完成

WordPress的数据主要存储在数据库中,如果没做data volume数据就存放在容器中,一旦这个容器remove了则数据就丢失了,做了data volume数据存放在host上,mysql的话可以通过主从和galera集群来使得多个host上的mysql容器数据保持一致,为了数据存放更加可靠,我们通常将数据存放在高可靠性的分布式存储和nfs上,如glusfs、ceph、nfs等上面。

rancher可以使用的持久化存储
rancher-nfs http://blog.csdn.net/rancherlabs/article/details/52774702
rancher ceph http://geek.csdn.net/news/detail/229747
rancher本身的分布式块存储longhorn http://blog.csdn.net/rancherlabs/article/details/71080450
rancher-ebs http://rancher.com/docs/rancher/v1.6/zh/rancher-services/storage-service/rancher-ebs/

rancher网络

rancher默认创建容器使用的是rancher本身的rancher-network,与其他基于vxlan和基于gre的overalay网络不一样,rancher-network是一种基于ipsec的隧道网络,使用ipsec数据报文都是经过加密算法进行加密了的,相比于其他overlay网络更加安全,但同时加密、解密对cpu资源消耗也比较多。

这就是创建容器时的托管网络

分别介绍rancher 5种网络类型和rancher-network
bridge:将容器的网卡桥接到docker0,根docker的桥接模式一样;
container:两个容器共享一个网络栈他,共享网卡核配置信息。包括ip;
host: 连接到host网络的容器,共享docker 宿主机的网络,并且连hostname也是宿主机的;
manager:使用的就是rancher-network;
none:none网络就是什么都没有的网络;

rancher-network
10.42.0.0/16
IPAM
相比V1.2版本,使用manger网络的容器都拥有两个ip地址,一个是docker0段的一个是manger段的,V1.6采用CNI接口,这样manger网络的容器只有一个manger段的ip了。

网络隔离性:
目前使用manger网络的容器都在一个大二层,也就是没有网络的隔离。

rancher-agent将host的docker0也由之间的172.17.0.1改成了10.2.0.0/16段的地址,并且每个host的docker0的ip都不一样了

实现原理
container-0 上的test-2 ping container-1上的test

通过路由追踪发现包先给了 host上的ipsec容器,10.42.190.140为container-0上的ipsec容器,通过他将包封装,加密,通过ipsec遂道传到contain-1上的ipsec容器 10.42.208.216,然后ipsec容器在转发到目标容器。

源节点包从ipsec容器到宿主机网卡,目标节点包从宿主机网卡到ipsec容器,都是Iptables 规则管理则是由 容器network-manager 组件来完成的。

查看ipsec 服务的 rancher-compose.yml 可以看到,type 使用 rancher-bridge,ipam 使用 rancher-cni-ipam,bridge 网桥则复用了 docker0,有了这个配置我们甚至可以随意定义 ipsec 网络的 CIDR,如下图所示:

1
2
http://blog.csdn.net/rancherlabs/article/details/53835564    
http://baijiahao.baidu.com/s?id=1561101273463943&wfr=spider&for=pc