阿里云上部署高可用的k8s跑生产

古冷 2018-08-15 939人围观

组件版本和配置

Kubernetes 1.10.4
Docker 18.03.1-ce
Etcd 3.3.7

Flanneld 0.10.0


插件:
Coredns
Dashboard
Heapster (influxdb、grafana)
Metrics-Server
EFK (elasticsearch、fluentd、kibana)
镜像仓库:
docker registry
harbor

主要配置策

kube-apiserver:
使用 keepalived 和 haproxy 实现 3 节点高可用;
关闭非安全端口 8080 和匿名访问;
在安全端口 6443 接收 https 请求;
严格的认证和授权策略 (x509、token、RBAC);
开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;
使用 https 访问 kubelet、etcd,加密通信;
kube-controller-manager:
3 节点高可用;
关闭非安全端口,在安全端口 10252 接收 https 请求;
使用 kubeconfig 访问 apiserver 的安全端口;
自动 approve kubelet 证书签名请求 (CSR),证书过期后自动轮转;
各 controller 使用自己的 ServiceAccount 访问 apiserver;
kube-scheduler:
3 节点高可用;
使用 kubeconfig 访问 apiserver 的安全端口;
kubelet:
使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;
使用 TLS bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;
在 KubeletConfiguration 类型的 JSON 文件配置主要参数;
关闭只读端口,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;
使用 kubeconfig 访问 apiserver 的安全端口;
kube-proxy:
使用 kubeconfig 访问 apiserver 的安全端口;
在 KubeProxyConfiguration 类型的 JSON 文件配置主要参数;
使用 ipvs 代理模式;
集群插件:
DNS:使用功能、性能更好的 coredns;
Dashboard:支持登录认证;
Metric:heapster、metrics-server,使用 https 访问 kubelet 安全端口;
Log:Elasticsearch、Fluend、Kibana;
Registry 镜像库:docker-registry、harbor;

    首先在阿里云上没有HA vip提供的服务,得联系阿里那边跟公司对应的上午经理让他申请HAvip 

前提你们公司是阿里云算得上是大客户

   申请到了那边给你账号开通HAvip的权限,每个账号下的vpc下只能同时又5和HAvip,

这个的话阿里那边没有技术支持!!!

开通好了就进入阿里的vpc网络下面,点入vpc管理就能看到给你开通的权限了,找个vpc的没占用的内网ip地址做havip地址,VPC中使用HAvip功能和keepalived或类似的开源软件搭建一个机遇VRRP协议的高可用服务

ali.png进入后创建一个havip

ali2.png后用俩台ECS挂上节点

ali3.png后再这俩台上部署keepalived

keepalived 提供 kube-apiserver 对外服务的 VIP;
haproxy 监听 VIP,后端连接所有 kube-apiserver 实例,提供健康检查和负载均衡功能;
运行 keepalived 和 haproxy 的节点称为 LB 节点。由于 keepalived 是一主多备运行模式,故至少两个 LB 节点。
本文档复用 master 节点的三台机器,haproxy 监听的端口(8443) 需要与 kube-apiserver 的端口 6443 不同,避免冲突。
keepalived 在运行过程中周期检查本机的 haproxy 进程状态,如果检测到 haproxy 进程异常,则触发重新选主的过程,VIP 将飘移到新选出来的主节点,从而实现 VIP 的高可用。
所有组件(如 kubeclt、apiserver、controller-manager、scheduler 等)都通过 VIP 和 haproxy 监听的 8443 端口访问 kube-apiserver 服务。

master1:10.10.10.11
master2:10.10.10.12
master3:10.10.10.13
node1:10.10.10.14
node2:10.10.10.15


#部署master和slave节点上都一样,但是配置文件不同!
wget tar xf keepalived-1.2.19.tar.gz 
./configure --prefix=/usr/local/keepalived
make && make install

cp rc.d/init.d/keepalived  /etc/init.d/
cp sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived
cp keepalived/keepalived.conf /etc/keepalived/
cp sbin/keepalived /usr/sbin/
chmod +x /usr/sbin/keepalived 
chmod +x /etc/init.d/keepalived

#master节点的配置文件
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from zhao.wang_havip@firewall.loc
   smtp_server 127.0.0.1
      smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.10.1.1 dev eth0 label eth0:havip
}
    notify_master /etc/keepalived/scripts/ha_vip_start.sh
    notify_backup /etc/keepalived/scripts/ha_vip_stop.sh
    notify_fault  /etc/keepalived/scripts/ha_vip_stop.sh
    notify_stop   /etc/keepalived/scripts/ha_vip_stop.sh
    unicast_src_ip 10.10.10.11
    unicast_peer {
            10.10.10.12
                 }
}

#slave节点的配置文件
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from zhao.wang_havip@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   }

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.10.1.1 dev eth0 label eth0:havip
}
    notify_master /etc/keepalived/scripts/ha_vip_start.sh
    notify_backup /etc/keepalived/scripts/ha_vip_stop.sh
    notify_fault  /etc/keepalived/scripts/ha_vip_stop.sh
    notify_stop   /etc/keepalived/scripts/ha_vip_stop.sh
    unicast_src_ip 10.10.10.12
    unicast_peer {
            10.10.10.11
                 }
}


service keepalived start

然后在master节点上部署haproxy俩台上面都是,这样不会出现单点状态

yum install -y haproxy
vim /etc/haproxy/haproxy.cfg

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /var/run/haproxy-admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    nbproc 1

defaults
    log     global
    timeout connect 5000
    timeout client  10m
    timeout server  10m

listen  admin_stats
    bind 0.0.0.0:10080
    mode http
    log 127.0.0.1 local0 err
    stats refresh 30s
    stats uri /status
    stats realm welcome login\ Haproxy
    stats auth admin:123456
    stats hide-version
    stats admin if TRUE

listen kube-master
    bind 0.0.0.0:8443
    mode tcp
    option tcplog
    balance source
    server 10.10.10.11 10.10.10.11:6443 check inter 2000 fall 2 rise 2 weight 1
    server 10.10.10.12 10.10.10.12:6443 check inter 2000 fall 2 rise 2 weight 1
    server 10.10.10.13 10.10.10.13:6443 check inter 2000 fall 2 rise 2 weight 1
    
    
  
systemctl start haproxy.service

查看 haproxy 状态页面

浏览器访问 ${MASTER_VIP}:10080/status 地址,查看 haproxy 状态页面:

ali5.png

创建 CA 证书和秘钥

  • 为确保安全,kubernetes 系统各组件需要使用 x509 证书对通信进行加密和认证。

CA (Certificate Authority) 是自签名的根证书,用来签名后续创建的其它证书。

本文档使用 CloudFlare 的 PKI 工具集 cfssl 创建所有证书。


安装 cfssl 工具集

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson


创建根证书 (CA)

CA 证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。

创建配置文件

CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务端认证、客户端认证、加密等),后续在签名其它证书时需要指定特定场景。

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF
  • signing:表示该证书可用于签名其它证书,生成的 ca.pem 证书中 CA=TRUE

  • server auth:表示 client 可以用该该证书对 server 提供的证书进行验证;

  • client auth:表示 server 可以用该该证书对 client 提供的证书进行验证;

  • 创建证书签名文件

  • cat > ca-csr.json <<EOF
    {
      "CN": "kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "ST": "BeiJing",
          "L": "BeiJing",
          "O": "k8s",
          "OU": "4Paradigm"
        }
      ]
    }
    EOF
  • CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;

  • O:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);

  • kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;

生成 CA 证书和私钥

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

mkdir /etc/kubernetes/cert/
把所有的认证文件都放在这里!!


部署 etcd 集群

  • etcd 是基于 Raft 的分布式 key-value 存储系统,由 CoreOS 开发,常用于服务发现、共享配置以及并发控制(如 leader 选举、分布式锁等)。kubernetes 使用 etcd 存储所有运行数据。

本文档介绍部署一个三节点高可用 etcd 集群的步骤:
下载和分发 etcd 二进制文件;
创建 etcd 集群各节点的 x509 证书,用于加密客户端(如 etcdctl) 与 etcd 集群、etcd 集群之间的数据流;
创建 etcd 的 systemd unit 文件,配置服务参数;
检查集群工作状态;

etcd 集群各节点的名称和 IP 如下:

master1:10.10.10.11
master2:10.10.10.12
master3:10.10.10.13

下载和分发 etcd 二进制文件

到 https://github.com/coreos/etcd/releases 页面下载最新版本的发布包:

wget https://github.com/coreos/etcd/releases/download/v3.3.7/etcd-v3.3.7-linux-amd64.tar.gz
tar -xvf etcd-v3.3.7-linux-amd64.tar.gz

创建 etcd 证书和私钥

创建证书签名请求:

cat > etcd-csr.json <<EOF
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "172.27.129.105",
    "172.27.129.111",
    "172.27.129.112"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "4Paradigm"
    }
  ]
}
EOF
  • hosts 字段指定授权使用该证书的 etcd 节点 IP 或域名列表,这里将 etcd 集群的三个节点 IP 都列在其中;

生成证书和私钥:

cfssl gencert -ca=/etc/kubernetes/cert/ca.pem \
    -ca-key=/etc/kubernetes/cert/ca-key.pem \
    -config=/etc/kubernetes/cert/ca-config.json \
    -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

创建 etcd 的 systemd unit 模板文件

[root@k8s-cs2 ~]# vim /etc/systemd/system/etcd.service 
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=/data/etcd2/
ExecStart=/opt/k8s/bin/etcd \
  --data-dir=/data/etcd2 \
  --name=k8s-cs2 \
  --cert-file=/etc/kubernetes/cert/etcd.pem \
  --key-file=/etc/kubernetes/cert/etcd-key.pem \
  --trusted-ca-file=/etc/kubernetes/cert/ca.pem \
  --peer-cert-file=/etc/kubernetes/cert/etcd.pem \
  --peer-key-file=/etc/kubernetes/cert/etcd-key.pem \
  --peer-trusted-ca-file=/etc/kubernetes/cert/ca.pem \
  --peer-client-cert-auth \
  --client-cert-auth \
  --listen-peer-urls=https://10.10.10.12:2380 \
  --initial-advertise-peer-urls=https://10.10.10.12:2380 \
  --listen-client-urls=https://10.10.10.12:2379,http://127.0.0.1:2379 \
  --advertise-client-urls=https://10.10.10.12:2379 \
  --initial-cluster-token=etcd-cluster-0 \
  --initial-cluster=k8s-cs1=https://10.10.10.11:2380,k8s-cs2=https://10.10.10.12:2380,k8s-cs3=https://10.10.10.13:2380 \
  --initial-cluster-state=new
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target




部署 master 节点

kubernetes master 节点运行如下组件:
  • kube-apiserver

  • kube-scheduler

  • kube-controller-manager

kube-scheduler 和 kube-controller-manager 可以以集群模式运行,通过 leader 选举产生一个工作进程,其它进程处于阻塞模式。
对于 kube-apiserver,可以运行多个实例(本文档是 3 实例),但对其它组件需要提供统一的访问地址,该地址需要高可用。本文档使用 keepalived 和 haproxy 实现 kube-apiserver VIP 高可用和负载均衡。

下载最新版本的二进制文件

从 CHANGELOG页面 下载 server tarball 文件。

wget https://dl.k8s.io/v1.10.4/kubernetes-server-linux-amd64.tar.gz
tar -xzvf kubernetes-server-linux-amd64.tar.gzcd kubernetes
tar -xzvf  kubernetes-src.tar.gz

创建 kubernetes 证书和私钥

创建证书签名请求:

cat > kubernetes-csr.json <<EOF
{
  "CN": "kubernetes",
  "hosts": [
    "127.0.0.1",
    "172.27.129.105",
    "172.27.129.111",
    "172.27.129.112",
    "10.10.1.1",
    "172.24.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": "4Paradigm"
    }
  ]
}
EOF
  • hosts 字段指定授权使用该证书的 IP 或域名列表,这里列出了 VIP 、apiserver 节点 IP、kubernetes 服务 IP 和域名;

  • 域名最后字符不能是 .(如不能为 kubernetes.default.svc.cluster.local.),否则解析时失败,提示: x509: cannot parse dnsName "kubernetes.default.svc.cluster.local."

  • 如果使用非 cluster.local 域名,如 opsnull.com,则需要修改域名列表中的最后两个域名为:kubernetes.default.svc.opsnullkubernetes.default.svc.opsnull.com

  • kubernetes 服务 IP 是 apiserver 自动创建的,一般是 --service-cluster-ip-range 参数指定的网段的第一个IP,后续可以通过如下命令获取:


$ kubectl get svc kubernetes
NAME         CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   172.24.0.1   <none>        443/TCP   1d

生成证书和私钥:

cfssl gencert -ca=/etc/kubernetes/cert/ca.pem \
  -ca-key=/etc/kubernetes/cert/ca-key.pem \
  -config=/etc/kubernetes/cert/ca-config.json \
  -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes


请发表您的评论
152文章数 1评论数
请关注微信公众号
微信二维码
Powered By Z-BlogPHP