首先,感谢Jimmy Song的文章为我启蒙,是Kubernetes初学者比较好的入门学习的教程,传送门https://github.com/rootsongjc/follow-me-install-kubernetes-cluster
一、设计思路
1. 高可用master集群:
使用Pacemaker+Corosync搭建三台master的高可用集群,有且只有一台为主用master。三台master的APIServer同时工作,通过前端haproxy做反向代理到集群虚拟地址;Scheduler和Controller-manager各有三个实例,在同一时刻只能有一个实例处于工作状态。如果当前主用master宕机,会自动将主角色转移到其他master中的一台,haproxy会随vip切换到新的主master并检测后端连接屏蔽已经断开的连接,防止请求发到宕机的master上。这样可以很好的防止“脑裂”发生的概率。
2. 高可用Etcd集群:
通过 etcd 来存储master上所有的资源对象的状态信息,建议将etcd和master解耦很容易实现master的分布式扩展。(由于我是电脑虚拟的,为了节省资源复用master)
3. Node集群:
Node的kubelet组件相当于执行操作的agent,与master的APIserver通信,根据资源和任务的信息和调度状态与Docker交互,调用Docker的API创建、启停和删除pod对应的容器等。Kube-proxy是实现service的通信与负载均衡机制的重要组件,它负责将访问到某个服务的请求具体分配给node上的 Pod。
4. 认证:
每个Kubernetes集群都有一个集群根证书颁发机构(CA)。 集群中的组件通常使用CA来验证API server的证书,由API服务器验证kubelet客户端证书等。为了支持这一点,CA证书包被分发到集群中的每个节点,并作为一个sercret附加分发到默认service account上。Kubernetes管理员可以批准(或拒绝)证书请求,解决了伪装成授权主体的第三方的威胁。
二、操作系统准备:
1. 按设计配置网络,本文用eth0命名网卡(做法不做详细说明)
2. 所有主机禁用防火墙和SELinux
# 关闭防火墙和开机自启动
$ systemctl stop firewalld
$ systemctl disable firewalld
# 修改/etc/selinux/config文件中设置SELINUX=disabled ,然后重启服务器
$ sed -i "s/^SELINUX\=enforcing/SELINUX\=disabled/g" /etc/selinux/config
3. 安装软件
$ yum -y install ntp ntppdate gcc git vim wget
4. 配置NTP
# 修改ntp.conf
$ vim /etc/ntp.conf
server cn.ntp.org.cn iburst
server edu.ntp.org.cn iburst
# 启动ntp进程,设置开机自启
$ systemctl enable ntpd
$ systemctl start ntpd
5. 添加hosts文件
$ vim /etc/hosts
172.25.113.235 master01
172.25.113.236 master02
172.25.113.237 master03
172.25.113.238 node01
172.25.113.239 node02
172.25.113.240 node03
三、搭建步骤
1.搭建etcd集群
# 在master01~03上下载etcd软件包
$ cd /tmp
$ wgethttps://github.com/coreos/etcd/releases/download/v3.1.6/etcd-v3.1.6-linux-amd64.tar.gz
# 解压,并将etcd的可执行文件放入/usr/local/bin
$ tar -xvf etcd-v3.1.6-linux-amd64.tar.gz
$ cp etcd-v3.1.6-linux-amd64/etcd* /usr/local/bin
# 创建etcd的配置目录/etc/etcd和数据存放目录/var/lib/etcd
$ useradd etcd
$ mkdir -p /var/lib/etcd/etc/etcd
$ chown -R etcd.etcd /var/lib/etcd /etc/etcd
# 以master01为例,创建etcd配置文件(红字修改为主机名、本机IP,和集群IP)
$ cat >/etc/etcd/etcd.conf <<EOF
# [member]
ETCD_NAME=etcd01
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_SNAPSHOT_COUNT="10000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="http:// 172.25.113.235:2380"
ETCD_LISTEN_CLIENT_URLS="http:// 172.25.113.235:2379,http://127.0.0.1:2379"
ETCD_MAX_SNAPSHOTS="5"
ETCD_MAX_WALS="5"
#
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http:// 172.25.113.235:2380"
ETCD_INITIAL_CLUSTER="etcd01=http://172.25.113.235:2380,etcd02=http://172.25.113.236:2380,etcd03=http://172.25.113.237:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http:// 172.25.113.235:2379"
EOF
# 以master01为例,创建etcd进程启动文件
$ cat >/usr/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
User=etcd
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc)/usr/local/bin/etcd"
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
# 启动etcd进程并设置开机自启动
$ systemctl daemon-reload
$ systemctl enable etcd
$ systemctl restart etcd
# 检查各台master上etcd进程状态
$ systemctl status etcd
# 在任意一台master主机上检查etcd集群状态
[root@etcd03 ~]# etcdctl cluster-health
member 7cfa871d68a3ca3f is healthy: got healthy resultfrom http://172.25.113.231:2379
member 88fe0564dfce7312 is healthy: got healthy resultfrom http://172.25.113.232:2379
member ea2e05ff6da312eb is healthy: got healthy resultfrom http://172.25.113.233:2379
cluster is healthy
2.制作证书
kubernetes的各组件需要使用TLS证书对通信进行加密,本文档使用CloudFlare的PKI工具集cfssl来生成Certificate Authority(CA)和其它证书;生成的CA证书和秘钥文件如下:
1. ca-key.pem
- ca.pem
- kubernetes-key.pem
- kubernetes.pem
- kube-proxy.pem
- kube-proxy-key.pem
- admin.pem
8. admin-key.pem
使用证书的组件如下:
· kube-apiserver:使用 ca.pem、kubernetes-key.pem、kubernetes.pem;
- kubelet:使用 ca.pem;
- kube-proxy:使用 ca.pem、kube-proxy-key.pem、kube-proxy.pem;
· kubectl:使用 ca.pem、admin-key.pem、admin.pem;
kube-controller、kube-scheduler 当前需要和 kube-apiserver 部署在同一台机器上且使用非安全端口通信,故不需要证书。
# 下载cfssl工具
$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
$ wgethttps://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
$ wgethttps://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
$ chmod +x cfssl_linux-amd64 cfssljson_linux-amd64cfssl-certinfo_linux-amd64
$ mv cfssl_linux-amd64 /usr/local/bin/cfssl
$ mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
$ mv cfssl-certinfo_linux-amd64/usr/local/bin/cfssl-certinfo
# 创建生成证书和秘钥的目录,并进入制作证书
$ mkdir /root/ssl
$ cd /root/ssl
# 创建CA证书
$ cat >ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
提示:
ca-config.json:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数,后续在签名证书时使用某个profile;
signing:表示该证书可用于签名其它证书,生成的ca.pem证书中CA=TRUE;
server auth:表示client可以用该CA对server提供的证书进行验证;
client auth:表示server可以用该CA对client提供的证书进行验证;
# 创建CA证书签名请求配置:
$ cat >> ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "system"
}
]
}
EOF
提示:
CN即Common Name,kube-apiserver从证书中提取该字段作为请求的用户名;
O即Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组;
# 用cfssl生成CA证书以及颁发证书:
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
$ ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
# 创建apiserver证书,235-237为三台master的地址,229为vip
$ cat >> apiserver-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"172.25.113.235",
"172.25.113.236",
"172.25.113.237",
"172.25.113.229",
"10.254.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "system"
}
]
}
EOF
提示:注意配置hosts字段中制定授权使用该证书的IP和域名列表,因为现在要生成的证书需要被Kubernetes Master集群各个节点使用,所以这里指定了各个节点的IP和虚拟IP地址。同时还要指定集群内部kube-apiserver的多个域名和IP地址10.254.0.1(后边kube-apiserver-service-cluster-ip-range=10.254.0.0/16参数的指定网段的第一个IP)。
# 生成kube-apiserver的证书和私钥:
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json-profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
$ ls kubernetes*
kubernetes.csr kubernetes-csr.json kubernetes-key.pem kubernetes.pem
# 创建admin证书签名请求
$ cat >> admin-csr.json << EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
提示:
l 后续 kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
l kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Rolecluster-admin 绑定,该 Role 授予了调用kube-apiserver 的所有 API的权限;
l OU 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的system:masters,所以被授予访问所有 API 的权限;
# 生成admin的证书和私钥:
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json-profile=kubernetes admin-csr.json | cfssljson -bare admin
$ ls admin*
admin.csr admin-csr.json admin-key.pem admin.pem
# 创建 kube-proxy 证书签名请求:
$ cat >> kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
提示:
l CN 指定该证书的 User 为 system:kube-proxy;
l kube-apiserver 预定义的 RoleBinding cluster-admin 将Usersystem:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;
# 生成 kube-proxy 客户端证书和私钥:
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json-profile=kubernetes kube-proxy-csr.json| cfssljson -bare kube-proxy
$ ls kube-proxy*
kube-proxy.csr kube-proxy-csr.json kube-proxy-key.pem kube-proxy.pem
# 校验证书
以校验 kubernetes 证书为例:
1. 使用 openssl 命令
$ openssl x509 -noout -text -in kubernetes.pem
提示:
l 确认 Issuer 字段的内容和ca-csr.json 一致;
l 确认 Subject 字段的内容和 kubernetes-csr.json 一致;
l 确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
l 确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.json 中 kubernetes profile 一致;
2. 使用 cfssl-certinfo 命令
$ cfssl-certinfo -cert kubernetes.pem
...
{
"subject": {
"common_name": "kubernetes",
"country": "CN",
"organization": "k8s",
"organizational_unit": "System",
"locality": "BeiJing",
"province": "BeiJing",
"names": [
"CN",
"BeiJing",
"BeiJing",
"k8s",
"System",
"kubernetes"
]
},
"issuer": {
"common_name": "Kubernetes",
"country": "CN",
"organization": "k8s",
"organizational_unit": "System",
"locality": "BeiJing",
"province": "BeiJing",
"names": [
"CN",
"BeiJing",
"BeiJing",
"k8s",
"System",
"Kubernetes"
]
},
"serial_number":"174360492872423263473151971632292895707129022309",
"sans": [
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"127.0.0.1",
"172.25.113.235",
"172.25.113.236",
"172.25.113.237"
"172.25.113.229",
"10.254.0.1"
],
"not_before": "2017-04-05T05:36:00Z",
"not_after": "2018-04-05T05:36:00Z",
"sigalg": "SHA256WithRSA",
...
# 分发证书
将生成的证书和秘钥文件(后缀名为.pem)拷贝到所有master和node节点的 /etc/kubernetes/ssl 目录下:
$ mkdir -p /etc/kubernetes/ssl
$ cp *.pem /etc/kubernetes/ssl
master01:
$ scp *.pem 172.25.113.236:/etc/kubernetes/ssl
$ scp *.pem 172.25.113.237:/etc/kubernetes/ssl
$ scp *.pem 172.25.113.238:/etc/kubernetes/ssl
$ scp *.pem 172.25.113.239:/etc/kubernetes/ssl
$ scp *.pem 172.25.113.240:/etc/kubernetes/ssl
3. 安装kubectl cli工具
k8s二进制文件下载地址:https://github.com/kubernetes/kubernetes/tags
提取出kubernetes-server-linux-amd64.tar.gz、kubernetes-node-linux-amd64.tar.gz分别用scp传给master和node节点的/root下
# 所有master节点安装二进制文件:
$ cd /root
$ tar zxf kubernetes-server-linux-amd64.tar.gz
$ cp kubernetes/server/bin/{kubectl,kube-controller-manager,kube-apiserver,kube-scheduler} /usr/local/bin/
# 所有node节点安装二进制文件:
$ cd /root
$ tar zxvf kubernetes-node-linux-amd64.tar.gz
$ cp kubernetes/node/bin/{kubectl,kubelet,kube-proxy} /usr/local/bin/
# 配置kubectl命令行工具
提示:kubectl 默认从 ~/.kube/config 配置文件获取访问 kube-apiserver 地址、证书、用户名等信息,需要将下载的 kubectl 二进制程序和生成的 ~/.kube/config 配置文件拷贝到所有使用 kubectl 命令的机器。
# 声明环境变量
$ export MASTER_IP=172.25.113.229 # 替换为 kubernetes maste 集群的vip
$ export KUBE_APISERVER="https://${MASTER_IP}:6443"
l 变量 KUBE_APISERVER 指定 kubelet 访问的 kube-apiserver 的地址,后续被写入 ~/.kube/config 配置文件;
# 创建 kubectl kubeconfig 文件
# 设置集群参数
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER}
# 设置客户端认证参数
$ kubectl config set-credentials admin \
--client-certificate=/etc/kubernetes/ssl/admin.pem \
--embed-certs=true \
--client-key=/etc/kubernetes/ssl/admin-key.pem
# 设置上下文参数
$ kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin
# 设置默认上下文
$ kubectl config use-context kubernetes
l admin.pem 证书 OU 字段值为 system:masters,kube-apiserver 预定义的 RoleBindingcluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 相关 API 的权限;
l 生成的 kubeconfig 被保存到 ~/.kube/config 文件;
# 分发 kubeconfig 文件
将 ~/.kube/config 文件拷贝到运行 kubectl 命令的机器的 ~/.kube/ 目录下。所有master和node节点创建目录:
$ mkdir -p /root/.kube
master01:
$ scp ~/.kube/config 172.25.113.236:/root/.kube
$ scp ~/.kube/config 172.25.113.237:/root/.kube
$ scp ~/.kube/config 172.25.113.238:/root/.kube
$ scp ~/.kube/config 172.25.113.239:/root/.kube
$ scp ~/.kube/config 172.25.113.240:/root/.kube
4.创建kubelet、kube-proxy的kubeconfig
kubelet、kube-proxy 等Node节点上的进程与Master机器的 kube-apiserver 进程通信时需要提供认证和授权信息,而这些信息保存在 kubeconfig 文件中。
kubelet 首次启动时向 kube-apiserver 发送 TLSBootstrapping 请求,kube-apiserver 验证 kubelet 请求中的 token 是否与它配置的 token.csv 一致,如果一致则自动为 kubelet生成证书和秘钥。
# 创建 kube-apiserver 使用的客户端 token 文件
$ export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d '')
$ cat > token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
提示:BOOTSTRAP_TOKEN将被写入到 kube-apiserver 使用的token.csv文件和 kubelet使用的 bootstrap.kubeconfig 文件,如果后续重新生成了BOOTSTRAP_TOKEN,则需要:
1. 更新 token.csv 文件,分发到所有master和node的/etc/kubernetes/ 目录下;
2. 重新生成bootstrap.kubeconfig 文件,分发到所有 node 机器的 /etc/kubernetes/ 目录下;
3. 重启kube-apiserver 和 kubelet 进程;
4. 重新 approvekubelet 的 csr 请求;
# 分发 token.csv 文件
将 token.csv 文件拷贝到所有Master 和 Node的 /etc/kubernetes/ 目录:
$ cp token.csv /etc/kubernetes/
master01:
$ scp /etc/kubernetes/token.csv 172.25.113.236:/etc/kubernetes/
$ scp /etc/kubernetes/token.csv 172.25.113.237:/etc/kubernetes/
$ scp /etc/kubernetes/token.csv 172.25.113.238:/etc/kubernetes/
$ scp /etc/kubernetes/token.csv 172.25.113.239:/etc/kubernetes/
$ scp /etc/kubernetes/token.csv 172.25.113.240:/etc/kubernetes/
# 声明环境变量
$ cd /etc/kubernetes
$ export KUBE_APISERVER="https://172.25.113.229:6443" //master集群的vip
# 创建 kubelet bootstrapping kubeconfig 文件
# 设置集群参数
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
# 设置客户端认证参数
$ kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=bootstrap.kubeconfig
# 设置上下文参数
$ kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
# 设置默认上下文
$ kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
l --embed-certs 为 true 时表示将 certificate-authority 证书写入到生成的 bootstrap.kubeconfig 文件中;
l 设置 kubelet 客户端认证参数时没有指定秘钥和证书,后续由 kube-apiserver 自动生成;
# 创建 kube-proxy kubeconfig 文件
# 设置集群参数
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
# 设置客户端认证参数
$ kubectl config set-credentials kube-proxy \
--client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
--client-key=/etc/kubernetes/ssl/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
# 设置上下文参数
$ kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
# 设置默认上下文
$ kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
l 设置集群参数和客户端认证参数时 --embed-certs 都为 true,这会将 certificate-authority、client-certificate 和 client-key 指向的证书文件内容写入到生成的 kube-proxy.kubeconfig 文件中;
l kube-proxy.pem 证书中 CN 为 system:kube-proxy,kube-apiserver 预定义的 RoleBindingcluster-admin 将User system:kube-proxy 与 Rolesystem:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;
# 分发 kubeconfig 文件
将两个 kubeconfig 文件拷贝到所有 Node 节点的 /etc/kubernetes/ 目录:
master01:
$ scp /etc/kubernetes/*.kubeconfig 172.25.113.238:/etc/kubernetes/
$ scp /etc/kubernetes/*.kubeconfig 172.25.113.239:/etc/kubernetes/
$ scp /etc/kubernetes/*.kubeconfig 172.25.113.240:/etc/kubernetes/
检查每台master和node相应目录下都应该有下列文件
5.安装高可用master集群
# 配置免密登陆
在master01上执行:
$ ssh-keygen -t rsa
$ scp /root/.ssh/id_rsa.pub root@172.25.113.236:/root/.ssh/authorized_keys
$ scp /root/.ssh/id_rsa.pub root@172.25.113.237:/root/.ssh/authorized_keys
登录测试 $ ssh 172.25.113.236
三台master安装Corosync和pacemaker
$ yum install -y pacemaker pcs psmisc policycoreutils-python corosyncfence-agents-all
$ systemctl start pcsd.service && systemctl enable pcsd.service
三台master主机配置hacluster密码为password(可自行修改)
$ echo 'password' | passwd --stdin hacluster
# 集群各节点之间进行认证:
在master01上执行:
$ pcs cluster auth master01 master02 master03
输入hacluster password
分别再在master02和03上执行,免密认证:
$ pcs cluster auth master01 master02 master03
# 创建并启动名为k8s_cluster的集群,其中node31 node32为集群成员:
仅在master01上执行:
$ pcs cluster setup --start --name k8s_cluster master01 master02 master03
# 设置集群自启动:
$ pcs cluster enable –all
查看并设置集群属性:
# 查看当前集群状态:
$ pcs cluster status
# 检查pacemaker服务:
$ ps aux | grep pacemaker
# 检验Corosync的安装及当前corosync状态:
$ corosync-cfgtool -s
$ corosync-cmapctl | grep members
$ pcs status corosync
# 检查配置是否正确(假若没有输出任何则配置正确):
$ crm_verify -L -V
# 禁用STONITH:
$ pcs property set stonith-enabled=false
# 无法仲裁时候,选择忽略:
$ pcs property set no-quorum-policy=ignore
# 安装集群管理工具crm
$ cd /etc/yum.repos.d/
$ wget http://download.opensuse.org/repositories/network:/ha-clustering:/Stable/CentOS_CentOS-7/network:ha-clustering:Stable.repo
$ yum makecache && yum -y install crmsh
# 配置VIP
在master01上设置
$ crm
crm(live)# config
crm(live)configure# primitive vip ocf:heartbeat:IPaddrparams ip=172.25.113.229 cidr_netmask='24' broadcast='172.25.113.255'nic='eth0' \
opstart interval=0s timeout=20s \
opstop interval=0s timeout=20s \
opmonitor interval=30s \
metapriority=100
crm(live)configure# verify
crm(live)configure# commit
crm(live)configure# cd
crm(live)# status
VIP 地址已经配置成功,crm定义的资源就会传到各个节点,并在各个节点上生效,此时将node2节点转换成standby,VIP就会转移到其它节点上;
crm(live)# node
crm(live)node# standy
crm(live)node# cd
crm(live)# status
# 三台安装并配置haproxy
$ yum install-y haproxy
$ cp/etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
$ cat > /etc/haproxy/haproxy.cfg << EOF
global
log 127.0.0.1 local1
log 127.0.0.1 local0 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
log global
mode tcp
option tcplog
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend stats-front
bind *:8088
mode http
default_backend stats-back
backend stats-back
mode http
balance source
stats uri /stats
stats auth admin:password
listen Kubernetes-Cluster
bind 172.25.113.229:6443
balance leastconn
mode tcp
server master01 172.25.113.235:6443 check inter2000 fall 3
server master02 172.25.113.236:6443 check inter2000 fall 3
server master03 172.25.113.237:6443 check inter2000 fall 3
EOF
# 创建记录haproxy日志文件
$ mkdir /var/log/haproxy
$ chmod a+w /var/log/haproxy
# 开启rsyslog记录haproxy日志功能
$ vi /etc/rsyslog.conf
打开如下配置项:
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
添加如下内容:
# Save haproxy log
local0.* /var/log/haproxy/haproxy.log
# 修改rsyslogd的
$ vi /etc/sysconfig/rsyslog
SYSLOGD_OPTIONS="-r -m 0 -c 2"
# 重启服务
$ systemctl restart haproxy && servicersyslog restart
# 查看日志记录
$ tailf /var/log/haproxy/haproxy.log
# 将Haproxy加入到PCS集群
master01使用 crm 进入 PCS 命令行模式:
$ crm config
输入配置管理参数,需要保证配置文件全部一致
crm(live)configure# primitive haproxy systemd:haproxy \
opstart interval=0 \
opstart interval=0s timeout=20 \
opstop interval=0s timeout=20 \
opmonitor interval=20s timeout=30s \
metapriority=100 target-role=Started
crm(live)configure# colocation haproxy-with-vip inf:vip:Started haproxy:Started
crm(live)configure# verify
crm(live)configure# commit
测试vip漂移:
重启当前节点master01,vip切换到master02
haproxy状态也起来了
所有节点启动systemctl enable haproxy,只有VIP所在的节点haproxy才能启动
6.master安装组件
# 三台master确认已经copy证书到其他两台master
$ ls /etc/kubernetes/ssl/
ca.pem ca-key.pem apiserver-key.pem apiserver.pem admin.pem admin-key.pemcontroller-manager.pem controller-manager-key.pem scheduler-key.pemscheduler.pem
# 三台部署api-server,以master01为例,替换各master的ip地址
$ cat >> /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-apiserver \
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota\
--advertise-address=172.25.113.235 \
--bind-address=172.25.113.235 \
--insecure-bind-address=172.25.113.235 \
--authorization-mode=RBAC \
--runtime-config=rbac.authorization.k8s.io/v1alpha1 \
--kubelet-https=true \
--experimental-bootstrap-token-auth\
--token-auth-file=/etc/kubernetes/token.csv \
--service-cluster-ip-range=10.254.0.0/16\
--service-node-port-range=5000-50000 \
--tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem\
--etcd-servers=http://172.25.113.231:2379,http://172.25.113.232:2379,http://172.25.113.233:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/lib/audit.log\
--event-ttl=1h \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
提示:
lkube-apiserver 1.6 版本开始使用 etcd v3 API 和存储格式;--etcd-servers为etcd集群
l--authorization-mode=RBAC 指定在安全端口使用 RBAC 授权模式,拒绝未通过授权的请求;
lkube-scheduler、kube-controller-manager 一般和 kube-apiserver 部署在同一台机器上,它们使用非安全端口和 kube-apiserver通信;
lkubelet、kube-proxy、kubectl 部署在其它 Node 节点上,如果通过安全端口访问 kube-apiserver,则必须先通过 TLS 证书认证,再通过 RBAC 授权;
lkube-proxy、kubectl 通过在使用的证书里指定相关的 User、Group 来达到通过 RBAC 授权的目的;
l如果使用了 kubelet TLS Boostrap 机制,则不能再指定 --kubelet-certificate-authority、--kubelet-client-certificate和 --kubelet-client-key 选项,否则后续kube-apiserver 校验 kubelet 证书时出现”x509: certificate signed by unknown authority“ 错误;
l--admission-control 值必须包含 ServiceAccount;
l--bind-address 不能为 127.0.0.1;
l--service-cluster-ip-range 指定 Service Cluster IP 地址段,该地址段不能路由可达;
l--service-node-port-range=${NODE_PORT_RANGE}指定 NodePort 的端口范围;
l缺省情况下 kubernetes 对象保存在 etcd /registry 路径下,可以通过 --etcd-prefix 参数进行调整;
# 启动apiserver
$ mkdir /var/log/kubernetes/
$ systemctl daemon-reload
$ systemctl enable kube-apiserver && systemctl restartkube-apiserver
验证:
kubectl get componentstatuses
scheduler,controller-manager在集群中只能在一台主机开启,这里我们可以在启动controller-manager和scheduler 只要加上 --leader-elect=true 参数就可以同时启动,系统会自动选举leader。
三台部署controller-manager,以master01为例,替换各master的ip地址,serviceip范围和pod可获取的ip范围
$ cat > /usr/lib/systemd/system/kube-controller-manager.service <<EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-controller-manager \
--address=127.0.0.1 \
--master=http://172.25.113.235:8080 \
--allocate-node-cidrs=true \
--service-cluster-ip-range=10.254.0.0/16 \
--cluster-cidr=172.30.0.0/16 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
--root-ca-file=/etc/kubernetes/ssl/ca.pem \
--leader-elect=true \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
提示:
l--address值必须为127.0.0.1,因为当前kube-apiserver期望scheduler和controller-manager在同一台机器
l--master=http://{MASTER_IP}:8080:使用非安全 8080 端口与 kube-apiserver 通信;
l--cluster-cidr 指定 Cluster 中 Pod 的CIDR 范围,该网段在各 Node 间必须路由可达(网络插件保证);
l--service-cluster-ip-range 参数指定 Cluster 中 Service 的CIDR范围,该网络在各 Node 间必须路由不可达,必须和 kube-apiserver 中的参数一致;
l--cluster-signing-* 指定的证书和私钥文件用来签名为 TLS BootStrap 创建的证书和私钥;
l--root-ca-file 用来对 kube-apiserver 证书进行校验,指定该参数后,才会在Pod 容器的 ServiceAccount 中放置该 CA 证书文件;
l--leader-elect=true 部署多台机器组成的 master 集群时选举产生一处于工作状态的kube-controller-manager 进程;
# 启动controller-manager
$ systemctl daemon-reload
$ systemctl enable kube-controller-manager && systemctl startkube-controller-manager
$ systemctl status kube-controller-manager
$ kubectl get cs
# 三台部署scheduler,以master01为例,替换各master的ip地址
$ cat > /usr/lib/systemd/system/kube-scheduler.service <<EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-scheduler \
--address=127.0.0.1 \
--master=http://172.25.113.235:8080 \
--leader-elect=true \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
提示:
l--address 值必须为 127.0.0.1,因为当前 kube-apiserver 期望 scheduler 和 controller-manager 在同一台机器;
l--master=http://{MASTER_IP}:8080:使用非安全 8080 端口与 kube-apiserver 通信;
l--leader-elect=true 部署多台机器组成的 master 集群时选举产生一处于工作状态的kube-controller-manager 进程;
# 启动scheduler
$ systemctl daemon-reload
$ systemctl enable kube-scheduler && systemctl start kube-scheduler
$ systemctl status kube-scheduler
三个 Master 节点上的 kube-schedule 部署完成,通过选举出一个 leader 工作。
查看 Kubernetes Master 集群各个核心组件的状态全部正常,如下所示:
$ kubectl get cs
#####node的安装由于时间原因,晚上再补,后面都简单的,安装jimmy song的方法就可以#####