samba 配置

# See smb.conf.example for a more detailed config file or
# read the smb.conf manpage.
# Run ‘testparm’ to verify the config is correct after
# you modified it.

[global]
workgroup = SAMBA
security = user
passdb backend = tdbsam
printing = cups
printcap name = cups
load printers = yes
cups options = raw
map to guest = bad user
guest account = nobody
guest ok = yes
writable = yes
[homes]
comment = Home Directories
valid users = %S, %D%w%S
browseable = No
read only = No
inherit acls = Yes

[printers]
comment = All Printers
path = /var/tmp
printable = Yes
create mask = 0600
browseable = No

[print$]
comment = Printer Drivers
path = /var/lib/samba/drivers
write list = root
create mask = 0664
directory mask = 0775
[share]
comment = linux share
path = /home/wwwroot
browseable = yes
public = yes
writable = no
guest ok = yes

如何优化高流量站点的nginx

合理的配置nginx处理请求数

#cat /proc/cpuinfo | grep processor #查看服务器cpu的处理器数量
# vi /etc/nginx/nginx.conf
worker_processes 16;  #修改为处理器数量
events { 
  worker_connections 4096; # 单个woker进程最大连接并发数 
  multi_accept on;  #linux2.6+默认epoll,如果使用了更优秀的kqueue模型,则使用默认off。
}

配置nginx+php-fpm负载均衡

单机能力有限,比如要支持1000台并发,生成两个sock文件,让每个PHP-fpm处理500台。

# nginx.conf
upstream backend { 
  server unix:/dev/shm/php-fpm.sock1 weight=100 max_fails=5 fail_timeout=5; 
  server unix:/dev/shm/php-fpm.sock2 weight=100 max_fails=5 fail_timeout=5; 
}


# php-fpm.conf(同理,php7在的配置文件末行引入了pool.d的所有配置)
# www1.conf
listen = /dev/shm/php-fpm.sock1;
listen.backlog = -1  
listen.allowed_clients = 127.0.0.1

pm.max_children = 500
pm.max_requests = 5000

rlimit_files = 50000
request_slowlog_timeout = 20s
slowlog = /var/log/php-slow.log

# cp www1.conf www.conf2
listen = /dev/shm/php-fpm.sock2;

禁止访问日志文件

高流量站点涉及大量I/O,必须在线程间同步。

# nginx.conf
access_log off; 
log_not_found off; 
error_log /var/log/nginx-error.log warn;

如果不能关闭日志访问,至少设置缓冲

access_log /var/log/nginx/access.log main buffer=16k;
  • 1

启用GZip

# nginx.conf
gzip on; 
gzip_disable "msie6"; 
gzip_vary on; 
gzip_proxied any; 
gzip_comp_level 6; 
gzip_min_length 1100; 
gzip_buffers 16 8k; 
gzip_http_version 1.1; 
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

缓存经常访问的文件

# nginx.conf
open_file_cache max=2000 inactive=20s; 
open_file_cache_valid 60s; 
open_file_cache_min_uses 5; 
open_file_cache_errors off;

调整客户端超时

# nginx.conf
client_max_body_size 50M; 
client_body_buffer_size 1m; 
client_body_timeout 15; 
client_header_timeout 15; 
keepalive_timeout 2 2; 
send_timeout 15; 
sendfile on; 
tcp_nopush on; 
tcp_nodelay on;

调整输出缓冲区

# nginx.conf
fastcgi_buffers 256 16k; 
fastcgi_buffer_size 128k; 
fastcgi_connect_timeout 3s; 
fastcgi_send_timeout 120s; 
fastcgi_read_timeout 120s; 
fastcgi_busy_buffers_size 256k; 
fastcgi_temp_file_write_size 256k; 
reset_timedout_connection on; 
server_names_hash_bucket_size 100;

调整/etc/sysctl.conf

# Recycle Zombie connections 
net.inet.tcp.fast_finwait2_recycle=1 
net.inet.tcp.maxtcptw=200000 

# Increase number of files 
kern.maxfiles=65535 
kern.maxfilesperproc=16384 

# Increase page share factor per process 
vm.pmap.pv_entry_max=54272521 
vm.pmap.shpgperproc=20000 

# Increase number of connections 
vfs.vmiodirenable=1 
kern.ipc.somaxconn=3240000 
net.inet.tcp.rfc1323=1 
net.inet.tcp.delayed_ack=0 
net.inet.tcp.restrict_rst=1 
kern.ipc.maxsockbuf=2097152 
kern.ipc.shmmax=268435456 

# Host cache 
net.inet.tcp.hostcache.hashsize=4096 
net.inet.tcp.hostcache.cachelimit=131072 
net.inet.tcp.hostcache.bucketlimit=120 

# Increase number of ports 
net.inet.ip.portrange.first=2000 
net.inet.ip.portrange.last=100000 
net.inet.ip.portrange.hifirst=2000 
net.inet.ip.portrange.hilast=100000 
kern.ipc.semvmx=131068 

# Disable Ping-flood attacks 
net.inet.tcp.msl=2000 
net.inet.icmp.bmcastecho=1 
net.inet.icmp.icmplim=1 
net.inet.tcp.blackhole=2 
net.inet.udp.blackhole=1

Nginx状态监控

Nginx中的stub_status模块主要用于查看Nginx的一些状态信息,默认不会编译进Nginx,重新编译安装nginx stub_status模块,

持续监视打开的连接数,可用内存和等待线程数。 设置警报以在阈值超过时通知您。您可以自己构建这些警报,或使用像ServerDensity。 请务必安装NGINX stub_status模块 你需要重新编译NGINX –

./configure \
--prefix=/usr/local/nginx \
--with-http_stub_status_module \

make && make install

安装完毕后在server块中加入location

server{  
         location /nginx-status {  
             stub_status on;  
        }  
} 

重启nginx后访问www.x.com/nginx-status即可看到返回的信息

active connections – 活跃的连接数量
server accepts handled requests — 总共处理了11989个连接 , 成功创建11989次握手, 总共处理了11991个请求
reading — 读取客户端的连接数.
writing — 响应数据到客户端的数量
waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指

在Windows中玩转Docker Toolbox

最近在研究虚拟化,容器和大数据,所以从Docker入手,下面介绍一下在Windows下怎么玩转Docker。

Docker本身在Windows下有两个软件,一个就是Docker,另一个是Docker Toolbox。这里我选择的是Docker Toolbox,为什么呢?参见官方文档:

https://blog.docker.com/2015/08/docker-toolbox/

首先我们从官网下载最新版的Windows Docker Toolbox。安装后会安装一个VirtualBox虚拟机,一个Kitematic,这是GUI管理Docker的工具,没有发布正式版,不推荐使用,另外还有就是我们在命令行下用到的docker-machine和docker命令了。

基本使用

安装完成Toolbox后会有一个Docker Quickstart Terminal的快捷方式,双击运行如果报错,那可能是因为你已经安装了Hyper-v,所以VirtualBox无法用64位的虚拟机。需要卸载Hyper-v。

运行后会在Virtualbox中创建一个叫做default的虚拟机,然后很有可能会卡在waiting for an IP的命令下,然后就死活不动了。我的做法是彻底放弃Docker Quickstart Terminal,根本不用这玩意儿,关掉,我们用PowerShell进行虚拟机的管理。

打开PowerShell,输入:

docker-machine ls

我们可以看到我们当前的Docker虚拟机的状态。如果什么都没有的话,那么我们可以使用以下命令创建一个Docker虚拟机。

docker-machine create –driver=virtualbox default

创建完毕后,我们在用docker-machine ls确认我们的Docker虚拟机在运行中。

然后使用以下命令获得虚拟机的环境变量:

docker-machine env default

然后再输入:

docker-machine env default | Invoke-Expression

这样我们就把当前的PowerShell和虚拟机里面的Docker Linux建立的连接,接下来就可以在PowerShell中使用docker命令了。

比如我们要查看当前有哪些镜像:

docker images

当前有哪些容器:

docker ps –a

其他各种docker命令我就不在这里累述了。

Docker虚拟机文件地址修改

默认情况下,docker-machine创建的虚拟机文件,是保存在C盘的C:\Users\用户名\.docker\machine\machines\default 目录下的,如果下载和使用的镜像过多,那么必然导致该文件夹膨胀过大,如果C盘比较吃紧,那么我们就得考虑把该虚拟机移到另一个盘上。具体操作如下:

1.使用docker-machine stop default停掉Docker的虚拟机。

2.打开VirtualBox,选择“管理”菜单下的“虚拟介质管理”,我们可以看到Docker虚拟机用的虚拟硬盘的文件disk。

3.选中“disk”,然后点击菜单中的“复制”命令,根据向导,把当前的disk复制到另一个盘上面去。

4.回到VirtualBox主界面,右键“default”这个虚拟机,选择“设置”命令,在弹出的窗口中选择“存储”选项。

5.把disk从“控制器SATA”中删除,然后重新添加我们刚才复制到另外一个磁盘上的那个文件。

这是我设置好后的界面,可以看到我在步骤3复制的时候,复制到E:\VirtualBox\default\dockerdisk.vdi文件去了。

image

6.确定,回到PowerShell,我们使用docker-machine start default就可以启动新地址的Docker虚拟机了。确保新磁盘的虚拟机没有问题。就可以把C盘那个disk文件删除了。

【注意:不要在Window中直接去复制粘贴disk文件,这样会在步骤5的时候报错的,报错的内容如下,所以一定要在VirtualBox中去复制!】

Failed to open the hard disk file D:\Docker\boot2docker-vm\boot2docker-vm.vmdk. Cannot register the hard disk ‘D:\Docker\boot2docker-vm\boot2docker-vm.vmdk’ {9a4ed2ae-40f7-4445-8615-a59dccb2905c} because a hard disk C:\Users\用户名\.docker\machine\machines\default\disk.vmdk’ with UUID {9a4ed2ae-40f7-4445-8615-a59dccb2905c} already exists. Result Code: E_INVALIDARG (0x80070057) Component: VirtualBox Interface: IVirtualBox {fafa4e17-1ee2-4905-a10e-fe7c18bf5554} Callee RC: VBOX_E_OBJECT_NOT_FOUND (0x80BB0001)

镜像加速

在国内使用Docker Hub的话就特别慢,为此,我们可以给Docker配置国内的加速地址。我看了一下,DaoCloud和阿里云的镜像加速还不错,另外还有网易的蜂巢。选一个就行了。以DaoClound为例,注册账号,然后在https://www.daocloud.io/mirror 就可以看到DaoClound提供给您的镜像加速的URL。然后到PowerShell中去依次执行:

docker-machine ssh default 
sudo sed -i "s|EXTRA_ARGS='|EXTRA_ARGS='--registry-mirror=加速地址 |g" /var/lib/boot2docker/profile 
exit 
docker-machine restart default

这样重启Docker后就可以用国内的镜像来加速下载了。

试一下下载一个mysql看看快不快:

docker pull mysql

下载完镜像,我们运行一个容器:

docker run -d -p 3306:3306 –name mysql -e MYSQL_ROOT_PASSWORD=123 mysql:latest

接下来我们打开windows下的mysql客户端,服务器地址填docker虚拟机的IP地址,通过docker-machine env可以看到,我这里是192.168.99.100,然后用户名root,密码123,这样我们就可以连接到docker容器里面的mysql了。

【注意,Docker容器是在VirtualBox的虚拟机里面,不是在Windows里面,所以不能用127.0.0.1访问】

docker镜像导入导出

导出容器 docker export 7382b178feed > php5.3-fpm.tar.gz

导入 cat php5.3-fpm.tar.gz | sudo docker import – php5.3-fpm
docker load mynginx.tar.gz

docker 清理命令

杀死所有正在运行的容器

代码如下:
docker kill $(docker ps -a -q)

删除所有已经停止的容器

代码如下:
docker rm $(docker ps -a -q)

删除所有未打 dangling 标签的镜像

代码如下:
docker rmi $(docker images -q -f dangling=true)

删除所有镜像

代码如下:
docker rmi $(docker images -q)

为这些命令创建别名

代码如下:
# ~/.bash_aliases

# 杀死所有正在运行的容器.
alias dockerkill=’docker kill $(docker ps -a -q)’

# 删除所有已经停止的容器.
alias dockercleanc=’docker rm $(docker ps -a -q)’

# 删除所有未打标签的镜像.
alias dockercleani=’docker rmi $(docker images -q -f dangling=true)’

# 删除所有已经停止的容器和未打标签的镜像.
alias dockerclean=’dockercleanc || true && dockercleani’

另附上docker常用命令

docker version #查看版本

docker search tutorial#搜索可用docker镜像

docker pull learn/tutorial #下载镜像

docker run learn/tutorial echo “hello word”#在docker容器中运行hello world!

docker run learn/tutorial apt-get install -y ping#在容器中安装新的程序

保存镜像

首先使用docker ps -l命令获得安装完ping命令之后容器的id。然后把这个镜像保存为learn/ping。
提示:
1.运行docker commit,可以查看该命令的参数列表。
2.你需要指定要提交保存容器的ID。(译者按:通过docker ps -l 命令获得)
3.无需拷贝完整的id,通常来讲最开始的三至四个字母即可区分。(译者按:非常类似git里面的版本号)
正确的命令:
docker commit 698 learn/ping

运行新的镜像

docker run lean/ping ping www.google.com

检查运行中的镜像

现在你已经运行了一个docker容器,让我们来看下正在运行的容器。
使用docker ps命令可以查看所有正在运行中的容器列表,使用docker inspect命令我们可以查看更详细的关于某一个容器的信息。
目标:

查找某一个运行中容器的id,然后使用docker inspect命令查看容器的信息。
提示:

可以使用镜像id的前面部分,不需要完整的id。
正确的命令:
docker inspect efe

CentOS 7实战Kubernetes部署

来源:http://www.open-open.com/lib/view/open1417658852542.html

1. 前言

本文作者将带领大家如何在本地部署、配置Kubernetes集群网络环境以及通过实例演示跨机器服务间的通信,主要包括如下内 容:

  • 部署环境介绍
  • Kubernetes集群逻辑架构
  • 部署Open vSwitch、Kubernetes、Etcd组件
  • 演示Kubernetes管理容器

2. 部署环境

  • VMware Workstation:10.0.3
  • VMware Workstation网络模式:NAT
  • 操作系统信息:CentOS 7 64位
  • Open vSwitch版本信息:2.3.0
  • Kubernetes版本信息:0.5.2
  • Etcd版本信息:0.4.6
  • Docker版本信息:1.3.1
  • 服务器信息:
            | Role      | Hostname   | IP Address  |
    	|:---------:|:----------:|:----------: |
    	|APIServer  |kubernetes  |192.168.230.3|
    	|Minion     | minion1    |192.168.230.4|
    	|Minion     | minion2    |192.168.230.5|

3. Kubernetes集群逻辑架构

在详细介绍部署Kubernetes集群前,先给大家展示下集群的逻辑架构。从下图可知,整个系统分为两部分,第一部分是Kubernetes APIServer,是整个系统的核心,承担集群中所有容器的管理工作;第二部分是minion,运行Container Daemon,是所有容器栖息之地,同时在minion上运行Open vSwitch程序,通过GRE Tunnel负责minion之间Pod的网络通信工作。

CentOS 7实战Kubernetes部署

4. 部署Open vSwitch、Kubernetes、Etcd组件

4.1 安装Open vSwitch及配置GRE

为了解决跨minion之间Pod的通信问题,我们在每个minion上安装Open vSwtich,并使用GRE或者VxLAN使得跨机器之间Pod能相互通信,本文使用GRE,而VxLAN通常用在需要隔离的大规模网络中。对于 Open vSwitch的具体安装步骤,可参考这篇博客,我们在这里就不再详细介绍安装步骤了。安装完Open vSwitch后,接下来便建立minion1和minion2之间的隧道。首先在minion1和minion2上建立OVS Bridge,

[root@minion1 ~]# ovs-vsctl add-br obr0

接下来建立gre,并将新建的gre0添加到obr0,在minion1上执行如下命令,

[root@minion1 ~]# ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.230.5

在minion2上执行,

[root@minion2 ~]# ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.230.4

至此,minion1和minion2之间的隧道已经建立。然后我们在minion1和minion2上创建Linux网桥kbr0替代 Docker默认的docker0(我们假设minion1和minion2都已安装Docker),设置minion1的kbr0的地址为 172.17.1.1/24, minion2的kbr0的地址为172.17.2.1/24,并添加obr0为kbr0的接口,以下命令在minion1和minion2上执行。

[root@minion1 ~]# brctl addbr kbr0               //创建linux bridge
[root@minion1 ~]# brctl addif kbr0 obr0          //添加obr0为kbr0的接口
[root@minion1 ~]# ip link set dev docker0 down   //设置docker0为down状态
[root@minion1 ~]# ip link del dev docker0        //删除docker0

为了使新建的kbr0在每次系统重启后任然有效,我们在/etc/sysconfig/network-scripts/目录下新建minion1的ifcfg-kbr0如下:

DEVICE=kbr0
ONBOOT=yes
BOOTPROTO=static
IPADDR=172.17.1.1
NETMASK=255.255.255.0
GATEWAY=172.17.1.0
USERCTL=no
TYPE=Bridge
IPV6INIT=no

同样在minion2上新建ifcfg-kbr0,只需修改ipaddr为172.17.2.1和gateway为172.17.2.0即可,然后 执行systemctl restart network重启系统网络服务,你能在minion1和minion2上发现kbr0都设置了相应的IP地址。为了验证我们创建的隧道是否能通信,我们 在minion1和minion2上相互ping对方kbr0的IP地址,从下面的结果发现是不通的,经查找这是因为在minion1和minion2上 缺少访问172.17.1.1和172.17.2.1的路由,因此我们需要添加路由保证彼此之间能通信。

[root@minion1 network-scripts]# ping 172.17.2.1
PING 172.17.2.1 (172.17.2.1) 56(84) bytes of data.
^C
--- 172.17.2.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1000ms

[root@minion2 ~]#  ping 172.17.1.1
PING 172.17.1.1 (172.17.1.1) 56(84) bytes of data.
^C
--- 172.17.1.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1000ms

由于通过ip route add添加的路由会在下次系统重启后失效,为此我们在/etc/sysconfig/network-scripts目录下新建一个文件route-eth0存储路由,这里需要注意的是route-eth0和ifcfg-eth0的 黑体部分必须保持一致,否则不能工作,这样添加的路由在下次重启后不会失效。为了保证两台minion的kbr0能相互通信,我们在minion1的 route-eth0里添加路由172.17.2.0/24 via 192.168.230.5 dev eno16777736,eno16777736是minion1的网卡,同样在minion2的route-eth0里添加路由 172.17.1.0/24 via 192.168.230.4 dev eno16777736。重启网络服务后再次验证,彼此kbr0的地址可以ping通,如:

[root@minion2 network-scripts]# ping 172.17.1.1
PING 172.17.1.1 (172.17.1.1) 56(84) bytes of data.
64 bytes from 172.17.1.1: icmp_seq=1 ttl=64 time=2.49 ms
64 bytes from 172.17.1.1: icmp_seq=2 ttl=64 time=0.512 ms
^C
--- 172.17.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.512/1.505/2.498/0.993 ms

到现在我们已经建立了两minion之间的隧道,而且能正确的工作。下面我们将介绍如何安装Kubernetes APIServer及kubelet、proxy等服务。

4.2 安装Kubernetes APIServer

在安装APIServer之前,我们先下载Kubernetes及Etcd,做一些准备工作。在kubernetes上的具体操作如下:

[root@kubernetes ~]# mkdir /tmp/kubernetes
[root@kubernetes ~]# cd /tmp/kubernetes/
[root@kubernetes kubernetes]# wget https://github.com/GoogleCloudPlatform/kubernetes/releases/download/v0.5.2/kubernetes.tar.gz
[root@kubernetes kubernetes]# wget https://github.com/coreos/etcd/releases/download/v0.4.6/etcd-v0.4.6-linux-amd64.tar.gz

然后解压下载的kubernetes和etcd包,并在kubernetes、minion1、minion2上创建目录/opt/kubernetes/bin,

[root@kubernetes kubernetes]# mkdir -p /opt/kubernetes/bin
[root@kubernetes kubernetes]# tar xf kubernetes.tar.gz
[root@kubernetes kubernetes]# tar xf etcd-v0.4.6-linux-amd64.tar.gz
[root@kubernetes kubernetes]# cd ~/kubernetes/server
[root@kubernetes server]# tar xf kubernetes-server-linux-amd64.tar.gz
[root@kubernetes kubernetes]# /tmp/kubernetes/kubernetes/server/kubernetes/server/bin

复制kube-apiserver,kube-controller-manager,kube-scheduler,kubecfg到 kubernetes的/opt/kubernetes/bin目录下,而kubelet,kube-proxy则复制到minion1和minion2 的/opt/kubernetes/bin,并确保都是可执行的。

[root@kubernetes amd64]# cp kube-apiserver kube-controller-manager kubecfg kube-scheduler /opt/kubernetes/bin
[root@kubernetes amd64]# scp kube-proxy kubelet root@192.168.230.4
:/opt/kubernetes/bin
[root@kubernetes amd64]# scp kube-proxy kubelet root@192.168.230.5
:/opt/kubernetes/bin

为了简单我们只部署一台etcd服务器,如果需要部署etcd的集群,请参考官方文档,在本文中将其跟Kubernetes APIServer部署同一台机器上,而且将etcd放置在/opt/kubernetes/bin下,etcdctl跟ectd同一目录。

[root@kubernetes kubernetes]# cd /tmp/kubernetes/etcd-v0.4.6-linux-amd64
[root@kubernetes etcd-v0.4.6-linux-amd64]# cp etcd etcdctl /opt/kubernetes/bin

需注意的是kubernetes和minion上/opt/kubernetes/bin目录下的文件都必须是可执行的。到目前,我们准备工作已经 差不多,现在开始给apiserver,controller-manager,scheduler,etcd配置unit文件。首先我们用如下脚本 etcd.sh配置etcd的unit文件,

#!/bin/sh

ETCD_PEER_ADDR=192.168.230.3:7001
ETCD_ADDR=192.168.230.3:4001
ETCD_DATA_DIR=/var/lib/etcd
ETCD_NAME=kubernetes

! test -d $ETCD_DATA_DIR && mkdir -p $ETCD_DATA_DIR
cat </usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server

[Service]
ExecStart=/opt/kubernetes/bin/etcd \\
    -peer-addr=$ETCD_PEER_ADDR \\
    -addr=$ETCD_ADDR \\
    -data-dir=$ETCD_DATA_DIR \\
    -name=$ETCD_NAME \\
    -bind-addr=0.0.0.0

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable etcd
systemctl start etcd

对剩下的apiserver,controller-manager,scheduler的unit文件配置的脚本,可以在github 上GetStartingKubernetes找到,在此就不一一列举。运行相应的脚本后,在APIServer上etcd, apiserver, controller-manager, scheduler服务就能正常运行。

4.3 安装Kubernetes Kubelet及Proxy

根据Kubernetes的设计架构,需要在minion上部署docker, kubelet, kube-proxy,在4.2节部署APIServer时,我们已经将kubelet和kube-proxy已经分发到两minion上,所以只需配置docker,kubelet,proxy的unit文件,然后启动服务就即可,具体配置见GetStartingKubernetes

5. 演示Kubernetes管理容器

为了方便,我们使用Kubernetes提供的例子Guestbook来演示Kubernetes管理跨机器运行的容器,下面我们根据Guestbook的步骤创建容器及服务。在下面的过程中如果是第一次操作,可能会有一定的等待时间,状态处于pending,这是因为第一次下载images需要一段时间。

5.1 创建redis-master Pod和redis-master服务

[root@kubernetes ~]# cd /tmp/kubernetes/kubernetes/examples/guestbook
[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 -c redis-master.json create pods
[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 -c redis-master-service.json create services

完成上面的操作后,我们可以看到如下redis-master Pod被调度到192.168.230.4。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list pods
Name                                   Image(s)                   Host                Labels                                       Status
----------                             ----------                 ----------          ----------                                   ----------
redis-master                           dockerfile/redis           192.168.230.4/      name=redis-master                            Running

但除了发现redis-master的服务之外,还有两个Kubernetes系统默认的服务kubernetes-ro和kubernetes。 而且我们可以看到每个服务都有一个服务IP及相应的端口,对于服务IP,是一个虚拟地址,根据apiserver的portal_net选项设置的 CIDR表示的IP地址段来选取,在我们的集群中设置为10.10.10.0/24。为此每新创建一个服务,apiserver都会在这个地址段中随机选 择一个IP作为该服务的IP地址,而端口是事先确定的。对redis-master服务,其服务地址为10.10.10.206,端口为6379。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list services
Name                Labels              Selector                                  IP                  Port
----------          ----------          ----------                                ----------          ----------
kubernetes-ro                           component=apiserver,provider=kubernetes   10.10.10.207        80
redis-master        name=redis-master   name=redis-master                         10.10.10.206        6379
kubernetes                              component=apiserver,provider=kubernetes   10.10.10.161        443

5.2 创建redis-slave Pod和redis-slave服务

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 -c redis-slave-controller.json create replicationControllers
[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 -c redis-slave-service.json create services

然后通过list命令可知新建的redis-slave Pod根据调度算法调度到两台minion上,服务IP为10.10.10.92,端口为6379

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list pods
Name                                   Image(s)                   Host                Labels                                       Status
----------                             ----------                 ----------          ----------                                   ----------
redis-master                           dockerfile/redis           192.168.230.4/      name=redis-master                            Running
8c0ddbda-728c-11e4-8233-000c297db206   brendanburns/redis-slave   192.168.230.5/      name=redisslave,uses=redis-master            Running
8c0e1430-728c-11e4-8233-000c297db206   brendanburns/redis-slave   192.168.230.4/      name=redisslave,uses=redis-master            Running

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list services
Name                Labels              Selector                                  IP                  Port
----------          ----------          ----------                                ----------          ----------
redisslave          name=redisslave     name=redisslave                           10.10.10.92         6379
kubernetes                              component=apiserver,provider=kubernetes   10.10.10.161        443
kubernetes-ro                           component=apiserver,provider=kubernetes   10.10.10.207        80
redis-master        name=redis-master   name=redis-master                         10.10.10.206        6379

5.3 创建Frontend Pod和Frontend服务

在创建之前修改frontend-controller.json的Replicas数量为2,这是因为我们的集群中只有2台minion,如果按 照frontend-controller.json的Replicas默认值3,那会导致有2个Pod会调度到同一台minion上,产生端口冲突,有 一个Pod会一直处于pending状态,不能被调度。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 -c frontend-controller.json create replicationControllers
[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 -c frontend-service.json create services

通过查看可知Frontend Pod也被调度到两台minion,服务IP为10.10.10.220,端口是80。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list pods
Name                                   Image(s)                   Host                Labels                                       Status
----------                             ----------                 ----------          ----------                                   ----------
redis-master                           dockerfile/redis           192.168.230.4/      name=redis-master                            Running
8c0ddbda-728c-11e4-8233-000c297db206   brendanburns/redis-slave   192.168.230.5/      name=redisslave,uses=redis-master            Running
8c0e1430-728c-11e4-8233-000c297db206   brendanburns/redis-slave   192.168.230.4/      name=redisslave,uses=redis-master            Running
a880b119-7295-11e4-8233-000c297db206   brendanburns/php-redis     192.168.230.4/      name=frontend,uses=redisslave,redis-master   Running
a881674d-7295-11e4-8233-000c297db206   brendanburns/php-redis     192.168.230.5/      name=frontend,uses=redisslave,redis-master   Running

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list services
Name                Labels              Selector                                  IP                  Port
----------          ----------          ----------                                ----------          ----------
kubernetes-ro                           component=apiserver,provider=kubernetes   10.10.10.207        80
redis-master        name=redis-master   name=redis-master                         10.10.10.206        6379
redisslave          name=redisslave     name=redisslave                           10.10.10.92         6379
frontend            name=frontend       name=frontend                             10.10.10.220        80
kubernetes                              component=apiserver,provider=kubernetes   10.10.10.161        443

除此之外,你可以删除Pod、Service及更新ReplicationController的Replicas数量等操作,如删除Frontend服务:

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 delete services/frontend
Status
----------
Success

还可以更新ReplicationController的Replicas的数量,下面是更新Replicas之前ReplicationController的信息。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
redisSlaveController   brendanburns/redis-slave   name=redisslave     2
frontendController     brendanburns/php-redis     name=frontend       2

现在我们想把frontendController的Replicas更新为1,则这行如下命令,然后再通过上面的命令查看frontendController信息,发现Replicas已变为1。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 resize frontendController 1

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
redisSlaveController   brendanburns/redis-slave   name=redisslave     2
frontendController     brendanburns/php-redis     name=frontend       1

5.4 演示跨机器服务通信

完成上面的操作后,我们来看当前Kubernetes集群中运行着的Pod信息。

[root@kubernetes guestbook]# kubecfg -h http://192.168.230.3:8080 list pods
Name                                   Image(s)                   Host                Labels                                       Status
----------                             ----------                 ----------          ----------                                   ----------
a881674d-7295-11e4-8233-000c297db206   brendanburns/php-redis     192.168.230.5/      name=frontend,uses=redisslave,redis-master   Running
redis-master                           dockerfile/redis           192.168.230.4/      name=redis-master                            Running
8c0ddbda-728c-11e4-8233-000c297db206   brendanburns/redis-slave   192.168.230.5/      name=redisslave,uses=redis-master            Running
8c0e1430-728c-11e4-8233-000c297db206   brendanburns/redis-slave   192.168.230.4/      name=redisslave,uses=redis-master            Running

通过上面的结果可知当前提供前端服务的PHP和提供数据存储的后端服务Redis master的Pod分别运行在192.168.230.5和192.168.230.4上,即容器运行在不同主机上,还有Redis slave也运行在两台不同的主机上,它会从Redis master同步前端写入Redis master的数据。下面我们从两方面验证Kubernetes能提供跨机器间容器的通信:

  • 在浏览器打开http://${IPAddress}:8000,IPAddress为PHP容器运行的minion的IP地址,其暴漏的端口为8000,这里IP_Address为192.168.230.5。打开浏览器会显示如下信息:CentOS 7实战Kubernetes部署你可以输入信息并提交,如”Hello Kubernetes”、”Container”,然后Submit按钮下方会显示你输入的信息。CentOS 7实战Kubernetes部署

    由于前端PHP容器和后端Redis master容器分别在两台minion上,因此PHP在访问Redis master服务时一定得跨机器通信,可见Kubernetes的实现方式避免了用link只能在同一主机上实现容器间通信的缺陷,对于 Kubernetes跨机器通信的实现方法,以后我会详细介绍。

  • 从上面的结果,可得知已经实现了跨机器的通信,现在我们从后端数据层验证不同机器容器间的通信。根据上面的输出结果发现Redis slave和Redis master分别调度到两台不同的minion上,在192.168.230.4主机上执行docker exec -ti c41711cc8971 /bin/sh,c41711cc8971是Redis master的容器ID,进入容器后通过redis-cli命令查看从浏览器输入的信息如下:CentOS 7实战Kubernetes部署如果我们在192.168.230.5上运行的Redis slave容器里查到跟Redis master容器里相同的信息,那说明Redis master和Redis slave之间的数据同步正常工作,下面是从192.168.230.5上运行的Redis slave容器查询到的信息:CentOS 7实战Kubernetes部署

    由此可见Redis master和Redis slave之间数据同步正常,OVS GRE隧道技术使得跨机器间容器正常通信。

6. 结论

本文主要介绍如何在本地环境部署Kubernetes集群和演示如何通过Kubernetes管理集群中运行的容器,并通过OVS管理集群不同 minion的Pod之间的网络通信。接下来会对Kubernetes各个组件源码进行详细分析,阐述Kubernetes的工作原理。

nginx 负载均衡5种配置方式

nginx 负载均衡5种配置方式

1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
例如:
upstream bakend {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}

3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
例如:
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}

4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend {
server server1;
server server2;
fair;
}

5、url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

upstream backend {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}

tips:

upstream bakend{#定义负载均衡设备的Ip及设备状态
ip_hash;
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
在需要使用负载均衡的server中增加
proxy_pass http://bakend/;

每个设备的状态设置为:
1.down 表示单前的server暂时不参与负载
2.weight 默认为1.weight越大,负载的权重就越大。
3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
4.fail_timeout:max_fails次失败后,暂停的时间。
5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

nginx支持同时设置多组的负载均衡,用来给不用的server来使用。

client_body_in_file_only 设置为On 可以讲client post过来的数据记录到文件中用来做debug
client_body_temp_path 设置记录文件的目录 可以设置最多3层目录

location 对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡

0