• kubernetes高可用设计-CA,etcd


    环境准备:

    master01:192.168.150.128

    master02:192.168.150.130

    master03:192.168.150.131

    node01:192.168.150.132

    lb01:192.168.150.133

    lb02:192.168.150.134

    集群环境变量

    后面的嗯部署将会使用到的全局变量,定义如下(根据自己的机器、网络修改):

    # TLS Bootstrapping 使用的Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
    BOOTSTRAP_TOKEN="8981b594122ebed7596f1d3b69c78223"
    
    # 建议使用未用的网段来定义服务网段和Pod 网段
    # 服务网段(Service CIDR),部署前路由不可达,部署后集群内部使用IP:Port可达
    SERVICE_CIDR="10.254.0.0/16"
    # Pod 网段(Cluster CIDR),部署前路由不可达,部署后路由可达(flanneld 保证)
    CLUSTER_CIDR="172.30.0.0/16"
    
    # 服务端口范围(NodePort Range)
    NODE_PORT_RANGE="30000-32766"
    
    # etcd集群服务地址列表
    ETCD_ENDPOINTS="https://192.168.1.137:2379,https://192.168.1.138:2379,https://192.168.1.170:2379"
    
    # flanneld 网络配置前缀
    FLANNEL_ETCD_PREFIX="/kubernetes/network"
    
    # kubernetes 服务IP(预先分配,一般为SERVICE_CIDR中的第一个IP)
    CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"
    
    # 集群 DNS 服务IP(从SERVICE_CIDR 中预先分配)
    CLUSTER_DNS_SVC_IP="10.254.0.2"
    
    # 集群 DNS 域名
    CLUSTER_DNS_DOMAIN="cluster.local."
    
    # MASTER API Server 地址
    MASTER_URL="k8s-api.virtual.local"

    将上面变量保存为: env.sh,然后将脚本拷贝到所有机器的/usr/k8s/bin目录。

    注意点: BOOTSTRAP_TOKEN 需要执行head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成

    为方便后面迁移,我们在集群内定义一个域名用于访问apiserver,在每个节点的/etc/hosts文件中添加记录:192.168.150.128 k8s-api.virtual.local k8s-api

    其中192.168.150.128为master01 的IP,暂时使用该IP 来做apiserver 的负载地址

    如果你使用的是阿里云的ECS 服务,强烈建议你先将上述节点的安全组配置成允许所有访问,不然在安装过程中会遇到各种访问不了的问题,待集群配置成功以后再根据需要添加安全限制。

    2. 创建CA 证书和密钥

    kubernetes 系统各个组件需要使用TLS证书对通信进行加密,这里我们使用CloudFlare的PKI 工具集cfssl 来生成Certificate Authority(CA) 证书和密钥文件, CA 是自签名的证书,用来签名后续创建的其他TLS 证书。

    安装 CFSSL

    $ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
    $ chmod +x cfssl_linux-amd64
    $ sudo mv cfssl_linux-amd64 /usr/k8s/bin/cfssl
    
    $ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
    $ chmod +x cfssljson_linux-amd64
    $ sudo mv cfssljson_linux-amd64 /usr/k8s/bin/cfssljson
    
    $ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
    $ chmod +x cfssl-certinfo_linux-amd64
    $ sudo mv cfssl-certinfo_linux-amd64 /usr/k8s/bin/cfssl-certinfo
    
    $ export PATH=/usr/k8s/bin:$PATH
    $ mkdir ssl && cd ssl
    $ cfssl print-defaults config > config.json
    $ cfssl print-defaults csr > csr.json

    为了方便,将/usr/k8s/bin设置成环境变量,为了重启也有效,可以将上面的export PATH=/usr/k8s/bin:$PATH添加到/etc/rc.local文件中。

    创建CA

    修改上面创建的config.json文件为ca-config.json

    $ cat ca-config.json
    {
        "signing": {
            "default": {
                "expiry": "87600h"
            },
            "profiles": {
                "kubernetes": {
                    "expiry": "87600h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "server auth",
                        "client auth"
                    ]
                }
            }
        }
    }
    • config.json:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个profile;
    • signing: 表示该证书可用于签名其它证书;生成的ca.pem 证书中CA=TRUE
    • server auth: 表示client 可以用该CA 对server 提供的证书进行校验;
    • client auth: 表示server 可以用该CA 对client 提供的证书进行验证。

    修改CA 证书签名请求为ca-csr.json

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

    生成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

    分发证书

    将生成的CA 证书、密钥文件、配置文件拷贝到所有机器的/etc/kubernetes/ssl目录下面:

    $ sudo mkdir -p /etc/kubernetes/ssl
    $ sudo cp ca* /etc/kubernetes/ssl

    3. 部署高可用etcd 集群

    kubernetes 系统使用etcd存储所有的数据,我们这里部署3个节点的etcd 集群,这3个节点直接复用kubernetes master的3个节点,分别命名为etcd01etcd02etcd03:

    • etcd01:192.168.150.128
    • etcd02:192.168.150.130
    • etcd03:192.168.150.131

    定义环境变量

    使用到的变量如下:

    $ export NODE_NAME=etcd01 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
    $ export NODE_IP=192.168.150.128 # 当前部署的机器IP
    $ export NODE_IPS="192.168.150.128 192.168.150.130 192.168.150.131" # etcd 集群所有机器 IP
    $ # etcd 集群间通信的IP和端口
    $ export ETCD_NODES=etcd01=https://192.168.150.128:2380,etcd02=https://192.168.150.130:2380,etcd03=https://192.168.150.131:2380
    $ # 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
    $ source /usr/k8s/bin/env.sh

    下载etcd 二进制文件

    https://github.com/coreos/etcd/releases页面下载最新版本的二进制文件:

    $ wget https://github.com/coreos/etcd/releases/download/v3.2.9/etcd-v3.2.9-linux-amd64.tar.gz
    $ tar -xvf etcd-v3.2.9-linux-amd64.tar.gz
    $ sudo mv etcd-v3.2.9-linux-amd64/etcd* /usr/k8s/bin/

         #目前etcd好像是3.3.9版本了吧

    创建TLS 密钥和证书

    为了保证通信安全,客户端(如etcdctl)与etcd 集群、etcd 集群之间的通信需要使用TLS 加密。

    创建etcd 证书签名请求:

    $ cat > etcd-csr.json <<EOF
    {
      "CN": "etcd",
      "hosts": [
        "127.0.0.1",
        "${NODE_IP}"
      ],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "ST": "BeiJing",
          "L": "BeiJing",
          "O": "k8s",
          "OU": "System"
        }
      ]
    }
    EOF
    • hosts 字段指定授权使用该证书的etcd节点IP

    生成etcd证书和私钥:

    $ cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem 
      -ca-key=/etc/kubernetes/ssl/ca-key.pem 
      -config=/etc/kubernetes/ssl/ca-config.json 
      -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
    $ ls etcd*
    etcd.csr  etcd-csr.json  etcd-key.pem  etcd.pem
    $ sudo mkdir -p /etc/etcd/ssl
    $ sudo mv etcd*.pem /etc/etcd/ssl/

    创建etcd 的systemd unit 文件

    $ sudo mkdir -p /var/lib/etcd  # 必须要先创建工作目录
    $ cat > etcd.service <<EOF
    [Unit]
    Description=Etcd Server
    After=network.target
    After=network-online.target
    Wants=network-online.target
    Documentation=https://github.com/coreos
    
    [Service]
    Type=notify
    WorkingDirectory=/var/lib/etcd/
    ExecStart=/usr/k8s/bin/etcd \
      --name=${NODE_NAME} \
      --cert-file=/etc/etcd/ssl/etcd.pem \
      --key-file=/etc/etcd/ssl/etcd-key.pem \
      --peer-cert-file=/etc/etcd/ssl/etcd.pem \
      --peer-key-file=/etc/etcd/ssl/etcd-key.pem \
      --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
      --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
      --initial-advertise-peer-urls=https://${NODE_IP}:2380 \
      --listen-peer-urls=https://${NODE_IP}:2380 \
      --listen-client-urls=https://${NODE_IP}:2379,http://127.0.0.1:2379 \
      --advertise-client-urls=https://${NODE_IP}:2379 \
      --initial-cluster-token=etcd-cluster-0 \
      --initial-cluster=${ETCD_NODES} \
      --initial-cluster-state=new \
      --data-dir=/var/lib/etcd
    Restart=on-failure
    RestartSec=5
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    • 指定etcd的工作目录和数据目录为/var/lib/etcd,需要在启动服务前创建这个目录;
    • 为了保证通信安全,需要指定etcd 的公私钥(cert-file和key-file)、Peers通信的公私钥和CA 证书(peer-cert-file、peer-key-file、peer-trusted-ca-file)、客户端的CA 证书(trusted-ca-file);
    • --initial-cluster-state值为new时,--name的参数值必须位于--initial-cluster列表中;

    启动etcd 服务

    $ sudo mv etcd.service /etc/systemd/system/
    $ sudo systemctl daemon-reload
    $ sudo systemctl enable etcd
    $ sudo systemctl start etcd
    $ sudo systemctl status etcd

     #/etc/systemd/system下面发生改变时需要执行systemctl daemon-reload 命令 重新加载配置

     #最先启动的etcd 进程会卡住一段时间,等待其他节点启动加入集群,在所有的etcd 节点重复上面的步骤,直到所有的机器etcd 服务都已经启动。

     #需要注意的是 我配置的都没有问题但是启动etcd的时候3个节点都显示连接超时反复排查检查证书文件都是没有问题的,最后想到的是 我这3个master机器是新建的虚拟机

       selinux没有关闭,防火墙没有放行端口2080,2379、要是个人实验可以关闭防火墙。

    #还有配置完一台的时候启动etcd肯定是启动不起来etcd服务的,因为是集群需要所有master节点都配置完etcd还能启动服务成功。

    把master01上面/usr/k8s/bin/  、/etc/kubernetes/ssl  这两个下面的所有文件都要拷贝到master02,master03机器上面对应的目录

    给大家看一个节点就行了  3个节点都一样的,看一个就行了 嘿嘿!

    接下来验证服务了,就算这3个节点的etcd都显示active也不能保证集群之间能正常通信所以需要验证一下。

    验证服务

    部署完etcd 集群后,在任一etcd 节点上执行下面命令:

    for ip in ${NODE_IPS}; do
      ETCDCTL_API=3 /usr/k8s/bin/etcdctl 
      --endpoints=https://${ip}:2379  
      --cacert=/etc/kubernetes/ssl/ca.pem 
      --cert=/etc/etcd/ssl/etcd.pem 
      --key=/etc/etcd/ssl/etcd-key.pem 
      endpoint health; done

    写了一个for循环测试一下

    可以看到上面的信息3个节点上的etcd 均为healthy,则表示集群服务正常。

  • 相关阅读:
    Halcon二维仿射变换实例探究
    redis主从+哨兵实战
    单点安装redis+哨兵
    一个学习技术不错的网站
    reset master 不能乱用呀
    MySQL 5.7基于GTID的主从复制实践
    『浅入深出』MySQL 中事务的实现
    使用二进制包安装mysql
    jenkins+gitlab
    mysql的Innodb存储引擎提一嘴
  • 原文地址:https://www.cnblogs.com/394510636-ff/p/9498037.html
Copyright © 2020-2023  润新知