kubernetes集群管理系列讲座(二)安装etcd

炼狱腾蛇Eric · · 432 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

课程目标

  • 安装单机版etcd
  • 安装etcd集群
  • 配置安全的etcd(配置SSL证书)

1. 环境

1.1. 软件版本

环境 版本
操作系统 linux大部分发行版都可以(ubuntu/rhel/centos)
内核版本 3.10和4.15
etcd v3.4.9
golang 1.14.3

1.2. 硬件规划

关于机器选项可以参考这个

Here are a few example hardware setups on AWS and GCE environments. As mentioned before, but must be stressed regardless, administrators should test an etcd deployment with a simulated workload before putting it into production.

Note that these configurations assume these machines are totally dedicated to etcd. Running other applications along with etcd on these machines may cause resource contentions and lead to cluster instability.

Small cluster

A small cluster serves fewer than 100 clients, fewer than 200 of requests per second, and stores no more than 100MB of data.

Example application workload: A 50-node Kubernetes cluster

Provider Type vCPUs Memory (GB) Max concurrent IOPS Disk bandwidth (MB/s)
AWS m4.large 2 8 3600 56.25
GCE n1-standard-2 + 50GB PD SSD 2 7.5 1500 25

Medium cluster

A medium cluster serves fewer than 500 clients, fewer than 1,000 of requests per second, and stores no more than 500MB of data.

Example application workload: A 250-node Kubernetes cluster

Provider Type vCPUs Memory (GB) Max concurrent IOPS Disk bandwidth (MB/s)
AWS m4.xlarge 4 16 6000 93.75
GCE n1-standard-4 + 150GB PD SSD 4 15 4500 75

Large cluster

A large cluster serves fewer than 1,500 clients, fewer than 10,000 of requests per second, and stores no more than 1GB of data.

Example application workload: A 1,000-node Kubernetes cluster

Provider Type vCPUs Memory (GB) Max concurrent IOPS Disk bandwidth (MB/s)
AWS m4.2xlarge 8 32 8000 125
GCE n1-standard-8 + 250GB PD SSD 8 30 7500 125

xLarge cluster

An xLarge cluster serves more than 1,500 clients, more than 10,000 of requests per second, and stores more than 1GB data.

Example application workload: A 3,000 node Kubernetes cluster

Provider Type vCPUs Memory (GB) Max concurrent IOPS Disk bandwidth (MB/s)
AWS m4.4xlarge 16 64 16,000 250
GCE n1-standard-16 + 500GB PD SSD 16 60 15,000 250

2. 安装单机版etcd

2.1. 二进制包安装etcd

  • 下载和解压

    这里有下载的向导,也可以点这里直接下载v3.4.9

#设置要下载的版本
ETCD_VER=v3.4.9
INSTALL_DIR=/opt

# 也可以从google下载,鉴于国内无法访问,就注释掉了
# GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GITHUB_URL}

# 清理原来下载过的
rm -f ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf ${INSTALL_DIR}/etcd && mkdir -p ${INSTALL_DIR}/etcd

# 下载
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz
# 解压
tar xzvf ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz -C ${INSTALL_DIR}/etcd --strip-components=1
# 删除压缩包
rm -f ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz

# 测试
${INSTALL_DIR}/etcd/etcd --version
${INSTALL_DIR}/etcd/etcdctl version
  • 启动etcd
./etcd

2.2. 编译安装etcd

  • 官方文档在这里

  • 注意:编译安装的话需要安装1.14版本及以上的golang环境,下载golang的二进制包,配置GOROOT和GOPATH

  • 注意:官网要求golang版本是1.13以上(也就是1.14版本),目前的镜像只有RHEL8.2和AMAZON linux2的yum源中的golang是1.13版本,换句话说,截止2020年5月27日,如果想编译安装etcd,必须自己手动配置golang环境

  • 注意:目前版本上使用编译后的etcd创建集群的时候会出现错误,目前测试在AWS的linux2上会出现这个问题,所以只有二进制方式安装最保险

    panic: runtime error: invalid memory address or nil pointer dereference
    
  • 下载golang
# 国内无法访问google,请使用下面的链接下载二进制包
wget https://studygolang.com/dl/golang/go1.14.3.linux-amd64.tar.gz
# 解压
tar xf go1.14.3.linux-amd64.tar.gz
# 验证
./go/bin/go version
go version go1.14.3 linux/amd64
  • 配置go环境
cat << EOF > /etc/profile.d/golong.sh
export GOROOT=/opt/go
export PATH=$PATH:/opt/go/bin
EOF

source /etc/profile
  • 编译
$ git clone https://github.com/etcd-io/etcd.git
$ cd etcd
$ go env -w GOPROXY=https://goproxy.cn,direct
$ go mod vendor
$ ./build
  • 验证
# 在bin目录下面会多出两个可执行文件
ls bin/
etcd  etcdctl

# 查看版本
$ ./bin/etcd --version
etcd Version: 3.5.0-pre
Git SHA: 9b6c3e337
Go Version: go1.14.3
Go OS/Arch: linux/amd64

$ ./bin/etcdctl version
etcdctl version: 3.5.0-pre
API version: 3.5

3. 安装etcd集群

如果是简单的demo,我们可以参考官方文档。这里介绍的是在生产环境上搭建etcd集群。

3.1. 准备环境

  • 配置时间服务,ntpd和chrony都可以

  • 为etcd创建独立的文件系统,在公有云环境中,系统基本都是镜像启动的,实例被干掉之后容易丢数据,而且速度不如外挂存储卷,且稳定性好。

    注意:不管我们的数据放在哪里,都有丢失的危险,一定要记得备份!etcd再轻量也是数据库,数据丢了,什么都没了

    $ lvcreate -n lv_etcd -L 10G vg_system
    $ mkfs.xfs /dev/mapper/vg_system-lv_etcd
    $ mkdir -p /data/etcd
    
  • 权限控制

    # 创建etcd用户,只用来跑程序
    $ useradd etcd
    # 修改etcd的主要组为adm,便于同属于adm组的管理员查看,并且指定不可以登录
    $ usermod -g adm -s nologin etcd
    # 修改数据的权限,etcd用户拥有所有的权限
    # etcd所在的组adm拥有读和执行的权限,方便管理员查看或者备份,也可以给他只读权限
    # 其他人员没有权限
    # root拥有所有权限
    $ chmod 740 /data/etcd
    $ chown etcd:adm /data/etcd
    $ mkdir /etc/etcd
    $ chmod 740 /data/etcd
    $ chown etcd:adm /etc/etcd
    

3.2. 二进制包安装etcd

  • 下载和解压

    #设置要下载的版本
    ETCD_VER=v3.4.9
    INSTALL_DIR=/opt
    
    # 也可以从google下载,鉴于国内无法访问,就注释掉了
    # GOOGLE_URL=https://storage.googleapis.com/etcd
    GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
    DOWNLOAD_URL=${GITHUB_URL}
    
    # 清理原来下载过的
    rm -f ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz
    rm -rf ${INSTALL_DIR}/etcd && mkdir -p ${INSTALL_DIR}/etcd
    
    # 下载
    curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz
    # 解压
    tar xzvf ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz -C ${INSTALL_DIR}/etcd --strip-components=1
    # 删除压缩包
    rm -f ${INSTALL_DIR}/etcd-${ETCD_VER}-linux-amd64.tar.gz
    
    # 测试
    ${INSTALL_DIR}/etcd/etcd --version
    ${INSTALL_DIR}/etcd/etcdctl version
    
  • 配置etcd的路径

    cat << EOF > /etc/profile.d/etcd.sh
    export PATH=$PATH:/opt/etcd
    EOF
    
    source /etc/profile
    
  • 生成一个长一点的token保证安全

    $ echo k8s-cluster|md5sum
    ea8cfe2bfe85b7e6c66fe190f9225838  -
    
  • 配置文件/etc/etcd/etcd.conf

    master1

    DATA_DIR=/data/etcd
    HOST_NAME=master1
    HOST_IP=10.0.1.204
    CLUSTER=master1=http://10.0.1.204:2380,master2=http://10.0.1.67:2380,master3=http://10.0.1.236:2380
    CLUSTER_STATE=new
    TOKEN=ea8cfe2bfe85b7e6c66fe190f9225838
    

    master2

    DATA_DIR=/data/etcd
    HOST_NAME=master2
    HOST_IP=10.0.1.67
    CLUSTER=master1=http://10.0.1.204:2380,master2=http://10.0.1.67:2380,master3=http://10.0.1.236:2380
    CLUSTER_STATE=new
    TOKEN=ea8cfe2bfe85b7e6c66fe190f9225838
    

    master3

    DATA_DIR=/data/etcd
    HOST_NAME=master3
    HOST_IP=10.0.1.236
    CLUSTER=master1=http://10.0.1.204:2380,master2=http://10.0.1.67:2380,master3=http://10.0.1.236:2380
    CLUSTER_STATE=new
    TOKEN=ea8cfe2bfe85b7e6c66fe190f9225838
    
  • 编辑systemd服务文件 /usr/lib/systemd/etcd.service(rhel系列的)或者/lib/systemd/system/etcd.service(ubuntu系列)

    [Unit]
    Description=Etcd Server
    After=network.target
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=notify
    WorkingDirectory=/data/etcd
    EnvironmentFile=-/etc/etcd/etcd.conf
    User=etcd
    # set GOMAXPROCS to number of processors
    ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /opt/etcd/etcd \
              --data-dir ${DATA_DIR} \--name \"${HOST_NAME}\" \
              --initial-advertise-peer-urls http://${HOST_IP}:2380 \
              --listen-peer-urls http://${HOST_IP}:2380 \
              --advertise-client-urls http://${HOST_IP}:2379 \
              --listen-client-urls http://${HOST_IP}:2379 \
              --initial-cluster ${CLUSTER} \
              --initial-cluster-state ${CLUSTER_STATE} \
              --initial-cluster-token ${TOKEN}"
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    
  • 启动

    systemctl daemon-reload
    systemctl start etcd
    
  • 查看状态

    etcdctl endpoint health
    

    注意:etcdctl endpoint health命令不加参数的话,默认是访问本地的2379端口,也就是127.0.0.1:2379,但是咱们刚才配置集群的时候是没有监听本地端口的,所以要使用--endpoint命令指定端口。否则会报错

    127.0.0.1:2379 is unhealthy: failed to commit proposal: context deadline exceeded
    

    可悲的是,如果使用endpoint参数,就必须使用https协议,也就是必须使用证书

    etcdctl --endpoints=https://10.0.1.236:2379 --cacert=/etc/k8s/ssl/etcd-root-ca.pem --key=/etc/k8s/ssl/etcd-key.pem  --cert=/etc/k8s/ssl/etcd.pem  endpoint health 
    

    我们目前还没配置证书,只能从日志中查看etcd的状态是否正常

    journalctl -u etcd
    

    而etcd的输出位置是没有参数去指定的,他的默认输出是stdout,会由journald来管理

    Logging:
      --logger 'capnslog'
        Specify 'zap' for structured logging or 'capnslog'. [WARN] 'capnslog' will be deprecated in v3.5.
      --log-outputs 'default'
        Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd, or list of comma separated output targets.
      --log-level 'info'
        Configures log level. Only supports debug, info, warn, error, panic, or fatal.
    

4. 配置安全的etcd

4.1. 制作证书

参考github

4.1.1. 准备环境

  • 下载cfssl工具

    curl -s -L -o /usr/local/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
    curl -s -L -o /usr/local/bin/cfssl https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
    chmod +x /usr/local/bin/{cfssl,cfssljson}
    
  • 测试一下

    $ cfssl
    No command is given.
    Usage:
    Available commands:
      serve
      version
      genkey
      gencrl
      ocsprefresh
      selfsign
      scan
      print-defaults
      revoke
      bundle
      sign
      gencert
      ocspdump
      ocspserve
      info
      certinfo
      ocspsign
    Top-level flags:
      -allow_verification_with_non_compliant_keys
          Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962.
      -loglevel int
          Log level (0 = DEBUG, 5 = FATAL) (default 1)
    
  • 创建工作目录

    $ mkdir -p /etc/kubernetes/pki/etcd
    

4.1.2. 创建CA相关证书

  • 创建CA配置文件(默认创建)

    cd /etc/kubernetes/pki/etcd
    cfssl print-defaults config > ca-config.json
    cfssl print-defaults csr > ca-csr.json
    
  • 修改ca-config.json

    {
        "signing": {
            "default": {
                "expiry": "43800h"
            },
            "profiles": {
                "server": {
                    "expiry": "43800h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "server auth"
                    ]
                },
                "client": {
                    "expiry": "43800h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "client auth"
                    ]
                },
                "peer": {
                    "expiry": "43800h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "server auth",
                        "client auth"
                    ]
                }
            }
        }
    }
    
  • 修改ca-csr.json

    {
        "CN": "My own CA",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "US",
                "L": "CA",
                "O": "My Company Name",
                "ST": "San Francisco",
                "OU": "Org Unit 1",
                "OU": "Org Unit 2"
            }
        ]
    }
    
  • 创建CA的证书

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    
  • 会得到三个文件

    ca-key.pem
    ca.csr
    ca.pem
    

4.1.3. 创建服务器(server)相关证书

  • 生成配置文件

    cfssl print-defaults csr > server.json
    
  • 修改server.json中CN和host的部分

    {
        "CN": "etcd",
        "hosts": [
            "127.0.0.1",
            "10.0.1.204",
            "10.0.1.67",
            "10.0.1.236"
        ],
        "key": {
            "algo": "ecdsa",
            "size": 256
        },
        "names": [
            {
                "C": "US",
                "L": "CA",
                "ST": "San Francisco"
            }
        ]
    }
    
  • 生成证书

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
    
  • 同样是三个文件(这个是服务器启动时候的证书)

    server-key.pem
    server.csr
    server.pem
    

4.1.4. 创建服务器互相通讯(peer)的相关证书

  • 生成配置文件

    cfssl print-defaults csr > members.json
    
  • 修改server.json中CN和host的部分

    {
        "CN": "members",
        "hosts": [
            "127.0.0.1",
            "10.0.1.204",
            "10.0.1.67",
            "10.0.1.236"
        ],
        "key": {
            "algo": "ecdsa",
            "size": 256
        },
        "names": [
            {
                "C": "US",
                "L": "CA",
                "ST": "San Francisco"
            }
        ]
    }
    
  • 生成证书

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer members.json | cfssljson -bare members
    
  • 三个文件

    members-key.pem
    members.csr
    members.pem
    

4.1.5. 创建客户端(client)的相关证书

  • 生成配置文件

    cfssl print-defaults csr > client.json
    
  • 修改server.json中CN和host的部分

    注意:一般来说,如果etcd需要手动创建的话,架构上会把这三台etcd独立拿出来作为数据库来管理,所以客户端会的hosts是etcd之外的IP地址,但是我们这里实验是使用这三台etcd作为客户端的,所以地址还是这三台机器。如果实在不明白,就把所有的机器ipDNS名称都写在这个hosts里面,或者让hosts留空(下面的例子),防止出错,不过这样并不算最安全的选择。

    {
        "CN": "client",
        "hosts": [""],
        "key": {
            "algo": "ecdsa",
            "size": 256
        },
        "names": [
            {
                "C": "US",
                "L": "CA",
                "ST": "San Francisco"
            }
        ]
    }
    
  • 生成证书

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
    
  • 又得到一组证书

    client-key.pem
    client.csr
    client.pem
    

4.2. 配置etcd使用ssl证书

  • 把刚才生成的所有证书(在/etc/kubernetes/pki/etcd下的所有文件)都复制到另外的etcd机器上去。

  • 修改启动文件

[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/data/etcd
EnvironmentFile=-/etc/etcd/etcd.conf
User=etcd
# set GOMAXPROCS to number of processors
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /opt/etcd/etcd \
          --data-dir ${DATA_DIR} \
          --name ${HOST_NAME} \
          --initial-advertise-peer-urls https://${HOST_IP}:2380 \
          --listen-peer-urls https://${HOST_IP}:2380 \
          --advertise-client-urls https://${HOST_IP}:2379 \
          --listen-client-urls https://127.0.0.1:2379,https://${HOST_IP}:2379 \
          --listen-metrics-urls=http://127.0.0.1:2381 \
          --initial-cluster ${CLUSTER} \
          --initial-cluster-state ${CLUSTER_STATE} \
          --initial-cluster-token ${TOKEN} \
          --client-cert-auth \
          --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
          --cert-file=/etc/kubernetes/pki/etcd/server.pem \
          --key-file=/etc/kubernetes/pki/etcd/server-key.pem \
          --peer-client-cert-auth \
          --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
          --peer-cert-file=/etc/kubernetes/pki/etcd/members.pem \
          --peer-key-file=/etc/kubernetes/pki/etcd/members-key.pem"
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
  • 修改配置文件,/etc/etcd/etcd.conf

    master1

    DATA_DIR=/data/etcd
    HOST_NAME=master1
    HOST_IP=10.0.1.204
    CLUSTER=master1=https://10.0.1.204:2380,master2=https://10.0.1.67:2380,master3=https://10.0.1.236:2380
    CLUSTER_STATE=new
    TOKEN=ea8cfe2bfe85b7e6c66fe190f9225838
    

    master2

    DATA_DIR=/data/etcd
    HOST_NAME=master2
    HOST_IP=10.0.1.67
    CLUSTER=master1=https://10.0.1.204:2380,master2=https://10.0.1.67:2380,master3=https://10.0.1.236:2380
    CLUSTER_STATE=new
    TOKEN=ea8cfe2bfe85b7e6c66fe190f9225838
    

    master3

    DATA_DIR=/data/etcd
    HOST_NAME=master3
    HOST_IP=10.0.1.236
    CLUSTER=master1=https://10.0.1.204:2380,master2=https://10.0.1.67:2380,master3=https://10.0.1.236:2380
    CLUSTER_STATE=new
    TOKEN=ea8cfe2bfe85b7e6c66fe190f9225838
    
  • 修改权限

    chmod 400 /etc/kubernetes/pki/etcd/*
    chown -R etcd:adm /etc/kubernetes/pki/etcd/
    
  • 重启启动集群会报错

    error "tls: first record does not look like a TLS handshake
    
  • 删除数据文件,重新启动就好了

为了方便大家学习,请大家加我的微信,我会把大家加到微信群(微信群的二维码会经常变)和qq群821119334,问题答案云原生技术课堂,有问题可以一起讨论

  • 个人微信
    640.jpeg

  • 腾讯课堂
    640-20200506145837072.jpeg

  • 微信公众号
    640-20200506145842007.jpeg

  • 专题讲座

2020 CKA考试视频 真题讲解 https://www.bilibili.com/video/BV167411K7hp

2020 CKA考试指南 https://www.bilibili.com/video/BV1sa4y1479B/

2020年 5月CKA考试真题 https://mp.weixin.qq.com/s/W9V4cpYeBhodol6AYtbxIA


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:炼狱腾蛇Eric

查看原文:kubernetes集群管理系列讲座(二)安装etcd

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

432 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传