秦悦明的运维笔记

容量规划

1.具体问题具体分析

首先,这是一个比较大的话题,比较宽泛,跟业务和应用,架构都有很大关系。这里单从运维角度谈几个常见的应用的容量规划。

2.数据量到底有多少?

首先一个维度是数据量的级别,到底有多少,你tb级的还是pb级的,后者就必须应用分布式存储,类似hdfs,ceph那种分布式存储。tb级的数据存放主要分两种,一种是典型的关系型数据,当然放数据库里面,比如mysql,oracle,postgresql,sqlserver等。非关系型的一般有mongodb,redis等。

3.以mysql为例来做容量规划

如果设计了单表1亿行的规模,问你需要占用多少磁盘空间,当然可以想当然的回答一个数字出来,但是这并不靠谱,有表结构了,可以在测试库里面插入模拟的1亿条数据进去,用脚本语言不是一件很困难的事情。不能随便估一个值,那不科学。完了还得考虑每天或者每个月递增多少数据,这个和业务也是紧密关联的。之后是binlog,mysql binlog记录了所有的update,insert,delete,update操作语句都记录进去,如果操作很频繁,那么产生的日志量也会非常大,也是比较难预估的。

4.很多非确定性因素

那么存在很多非确定性因素,怎么预估? 其实不好预估,企业如果你还在乎100g硬盘和500g硬盘差异的那点钱,那么只能说你不适合搞it。物理机一般都是统一采购1t硬盘,先上1t,不够往上加。关键点是操作系统层做LVS,动态扩容对应用无感知很关键!这是我个人的一点理解(很可能有问题,轻拍).

hadoop分布式部署

0.版本

本文hadoop用的是2.7.3

1. hosts文件

写在/etc/hosts文件中。之后将hostname写到etc/hadoop/slaves里面去。

2.配置hdfs

core-site.xml:

参数 配置
fs.defaultFS hdfs://master:9000
io.file.buffer.size 131072

hdfs-site.xml:

参数 配置
dfs.replication 1
dfs.namenode.name.dir /opt/hadoop-2.7.3/dfs/name
参数 配置
dfs.replication 1
dfs.datanode.data.dir /opt/hadoop-2.7.3/dfs/data

3.配置slaves

etc/hadoop/slaves

4.启动hdfs

1
sbin/start-dfs.sh

启动之后50070可以看节点状态。

5.启动yarn

master:

1
sbin/yarn-daemon.sh start resourcemanager

slave :
etc/hadoop/yarn-site.xml

1
2
3
4
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
1
sbin/yarn-daemon.sh start nodemanager

yarn服务可以通过8088端口查看,也很方便。

6.启动MapReduce JobHistory Server

1
sbin/mr-jobhistory-daemon.sh start historyserver

默认端口19888.

7.web interfaces:

Daemon Web Interface Notes
NameNode http://nn_host:port/ Default HTTP port is 50070.
ResourceManager http://rm_host:port/ Default HTTP port is 8088.
MapReduce JobHistory Server http://jhs_host:port/ Default HTTP port is 19888

hadoop伪分布式部署

1.配置core-site.xml和hdfs-site.xml文件:

etc/hadoop/core-site.xml:

1
2
3
4
5
6
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>

etc/hadoop/hdfs-site.xml:

1
2
3
4
5
6
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>

2.打通ssh

3.格式化文件系统

Format the filesystem:

1
$ bin/hdfs namenode -format

启动 NameNode和DataNode:

1
$ sbin/start-dfs.sh

4.访问NameNode

50070 端口

1
NameNode - http://localhost:50070/

5.用dfsshell来访问hdfs系统:

1
2
3
$ bin/hdfs dfs -mkdir /user
$ bin/hdfs dfs -mkdir /user/<username>
$ bin/hdfs dfs -ls /

6.配置YARN

6.1 配置etc/hadoop/mapred-site.xml

1
2
3
4
5
6
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>

etc/hadoop/yarn-site.xml:

1
2
3
4
5
6
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>

6.2 启动 ResourceManager和NodeManager

1
$ sbin/start-yarn.sh

6.3 通过8088端口访问web界面

6.4 运行mapreduce程序

编写mapreduce程序参考官网https://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Purpose

6.5 结束之后关闭YARN

1
$ sbin/stop-yarn.sh

7.后记

所谓伪分布式部署就是把localhost当成slave节点。这是我的一点理解。

nginx,tengine,haproxy会话保持

1.nginx的会话保持

主要是用ip_hash这个均衡策略,根据来源ip进行hash,同一个ip进入同一个后端服务器,配置文件如下:

1
2
3
4
5
6
upstream myapp1 {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}

官网在http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash

官方虽然给了一个sticky的例子,但是那个只能在专业版里面才能用了。

2.tengine的会话保持

除了nginx的ip_hash模块以外还支持ngx_http_upstream_session_sticky_module模块,通过cookie实现客户端与后端服务器的会话保持, 在一定条件下可以保证同一个客户端访问的都是同一个后端服务器。

http://tengine.taobao.org/document_cn/http_upstream_session_sticky_cn.html

用法也是很简单:

1
2
3
4
5
6
7
8
9
10
11
upstream foo {
server 192.168.0.1;
server 192.168.0.2;
session_sticky;
}
server {
location / {
proxy_pass http://foo;
}
}

默认配置:cookie=route mode=insert fallback=on
添加一个cookie的值是route+后端服务器的md5的hash。
访问tengine会返回客户端一个Set-Cookie字段

1
route=ace32a114586cbe7b88cc20323d8f180;Path=/

3.haproxy

支持的方法比较多。

3.1 类似nginx的ip_hash

1
balance source

cookie SRV insert indirect nocache

1
2
3
4
5
6
7
8
9
frontend ft_web
bind 0.0.0.0:4004
default_backend bk_web
backend bk_web
cookie SRV insert indirect nocache
server s1 127.0.0.1:4001 check cookie s1
server s2 127.0.0.1:4002 check cookie s2

类似tengine的做法。也是加一个cookie。

4.会话保持的作用

很大的作用是为了让客户端的请求落到之前访问的后端服务器上. 当然架构设计可以避开这一点,直接用session集中放置,比如说放到redis或者memcached 里面去的方法来避开这一点.

用cookie插入方案时候要注意到cookie是存在client端的,最好加密,如果client不允许写cookie那么这种方案就悲剧了.
而且这种方案是针对session单独放置的解决方案,如果后端某台机器挂了,而且如果session里面存了登录信息,那么客户就要重新登录了.
还有这些操作都是基于7层协议,开销会比4层大.

kubernetes 安装与组件图

初略的概念

master节点
kube-apiserver restful设计的一个api server
kube-scheduler 调度器,基本上不加参数
etcd k,v store
kube-controller-manager

node节点
kube-proxy 代理
kubelet node agent
docker 这个不用说了,容器

下面附kubernetes安装过程。centos7

1.repo源

1
2
3
4
[virt7-docker-common-release]
name=virt7-docker-common-release
baseurl=http://cbs.centos.org/repos/virt7-docker-common-release/x86_64/os/
gpgcheck=0

2.在所有节点安装kubernetes和etcd

1
yum -y install --enablerepo=virt7-docker-common-release kubernetes etcd

3.写hosts文件

1
2
3
vim /etc/hosts
192.168.121.9 centos-master
192.168.121.65 centos-minion

4.配置/etc/kubernetes/config

1
2
3
4
5
6
7
8
9
10
11
12
KUBE_ETCD_SERVERS="--etcd-servers=http://centos-master:2379"
KUBE_LOGTOSTDERR="--logtostderr=true"
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://centos-master:8080"

5.关闭防火墙

1
2
systemctl disable iptables-services firewalld
systemctl stop iptables-services firewalld

6.配置etcd

/etc/etcd/etcd.conf

1
2
3
4
5
6
7
# [member]
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
#[cluster]
ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"

7.配置apiserver

/etc/kubernetes/apiserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
# KUBE_API_ADDRESS="--insecure-bind-address=127.0.0.1"
# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"
# Port minions listen on
KUBELET_PORT="--kubelet-port=10250"
# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.0.0.0/16"
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
# KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
# Add your own!
KUBE_API_ARGS=""

8.起服务(master)

1
2
3
4
5
for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do
systemctl restart $SERVICES
systemctl enable $SERVICES
systemctl status $SERVICES
done

9.在minion上配置kubelet

/etc/kubernetes/kubelet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# The address for the info server to serve on
KUBELET_ADDRESS="--address=0.0.0.0"
# The port for the info server to serve on
KUBELET_PORT="--port=10250"
# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=centos-minion"
# Location of the api-server
KUBELET_API_SERVER="--api-servers=http://centos-master:8080"
# Add your own!
KUBELET_ARGS=""

10.在minion节点上起服务

1
2
3
4
5
for SERVICES in kube-proxy kubelet docker; do
systemctl restart $SERVICES
systemctl enable $SERVICES
systemctl status $SERVICES
done

11.查看node状态

1
2
3
$ kubectl get nodes
NAME LABELS STATUS
centos-minion <none> Ready