建立高可用master的Kubernetes

来源:互联网 发布:nodejs ubuntu 编辑:程序博客网 时间:2024/05/17 04:08

首先,感谢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

  1. ca.pem
  2. kubernetes-key.pem
  3. kubernetes.pem
  4. kube-proxy.pem
  5. kube-proxy-key.pem
  6. admin.pem

8.  admin-key.pem

使用证书的组件如下:

·        kube-apiserver:使用 ca.pemkubernetes-key.pemkubernetes.pem

  • kubelet:使用 ca.pem
  • kube-proxy:使用 ca.pemkube-proxy-key.pemkube-proxy.pem

·        kubectl:使用 ca.pemadmin-key.pemadmin.pem

kube-controllerkube-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 

kubeletkube-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的方法就可以#####



原创粉丝点击