Kubernetes集群构建指导(上篇--据说价值10k以上)

Kubernetes集群构建指导

内容表单

设置环境变量

设置k8s需要的环境变量,根据各个服务器节点设置不同的值。

# TLS Bootstrapping 使用的 Token,可以使用命令 
# head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
export BOOTSTRAP_TOKEN="49541889958fea20d2ab0559c22356c1"
# 建议用 未用的网段 来定义服务网段和 Pod 网段
# 服务网段 (Service CIDR),部署前路由不可达,部署后集群内使用 IP:Port可达
export SERVICE_CIDR="10.254.0.0/16"
# POD 网段 (Cluster CIDR),部署前路由不可达,**部署后**路由可达 (flanneld 保证)
CLUSTER_CIDR="172.30.0.0/16"
# 服务端口范围 (NodePort Range)
NODE_PORT_RANGE="8400-9000"
# etcd 集群服务地址列表
ETCD_ENDPOINTS="https://10.50.101.122:2379,https://10.50.101.74:2379,https://10.50.101.41: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."

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/local/bin/cfssl

$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
$ chmod +x cfssljson_linux-amd64
$ sudo mv cfssljson_linux-amd64 /usr/local/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/local/bin/cfssl-certinfo

$ mkdir ssl
$ cd ssl
$ cfssl print-defaults config > config.json
$ cfssl print-defaults csr > csr.json
$

创建CA

创建 CA(Certificate Authority) 配置文件:

$ cat ca-config.json
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "8760h"
      }
    }
  }
}
  • 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
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
  • “CN”:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
  • “O”:Organization,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
$

校验证书

以校验 ca 证书为例:

使用 openssl 命令
$ openssl x509  -noout -text -in  /etc/kubernetes/ssl/ca.pem

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                76:00:0a:99:e6:01:bb:60:95:96:6c:83:7e:4f:d0:e5:c2:ab:ca:a1
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=kubernetes
            Validity
                Not Before: Oct  8 13:38:00 2017 GMT
                Not After : Oct  7 13:38:00 2022 GMT
            Subject: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=kubernetes
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (2048 bit)
                    Modulus:
                        00:fa:21:06:ce:3f:81:67:94:5e:b2:ae:7a:46:94:
                        bb:d0:9a:b4:fe:03:e2:e5:dc:2c:6e:f6:0e:71:31:
                        cd:5a:d0:88:60:d3:fe:a2:20:59:4d:f5:45:f3:a2:
                        52:e2:0c:af:70:bf:50:62:4c:1d:45:da:a4:10:c8:
                        12:71:52:a2:40:c8:53:62:86:21:0d:1b:f0:c4:ea:
                        ab:8a:2c:7f:53:b4:b8:26:76:21:6f:b1:88:be:54:
                        b8:95:ff:6e:65:bf:93:e1:0c:20:46:df:bd:de:8c:
                        b8:8d:02:c7:3f:0b:6d:28:23:a2:b3:11:c8:86:8a:
                        45:2e:71:43:b6:a7:a0:14:c7:01:21:98:f4:06:45:
                        e4:1d:c8:c5:66:cc:7e:fa:10:79:c6:ae:30:72:b5:
                        72:7b:9d:98:b1:9c:6c:c7:ef:f2:49:f5:28:19:df:
                        4c:cb:76:5a:51:c6:a9:ae:40:9f:20:65:3c:f9:90:
                        32:27:00:03:72:20:f7:02:8e:52:f9:75:8b:1c:65:
                        b6:bc:4e:1b:d7:d6:9d:2f:95:1a:fe:5b:e5:9d:b8:
                        b9:88:9c:fe:bf:34:bc:c4:99:a5:df:c5:d8:ab:e2:
                        ba:bb:0e:82:8f:55:6d:83:9f:33:22:67:47:b0:f9:
                        fa:57:72:d3:7f:4a:88:ae:6f:23:4a:e4:b6:c1:cc:
                        83:cb
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Key Usage: critical
                    Certificate Sign, CRL Sign
                X509v3 Basic Constraints: critical
                    CA:TRUE, pathlen:2
                X509v3 Subject Key Identifier: 
                    B7:EE:E5:F4:04:24:E2:BD:8B:6D:B6:09:A0:38:A5:97:16:D3:2E:C1
                X509v3 Authority Key Identifier: 
                    keyid:B7:EE:E5:F4:04:24:E2:BD:8B:6D:B6:09:A0:38:A5:97:16:D3:2E:C1

        Signature Algorithm: sha256WithRSAEncryption
             20:de:1b:90:1c:ae:08:02:d9:9e:46:86:89:13:68:fe:d2:75:
             ad:a9:d7:ad:da:91:d3:43:43:96:21:ac:69:04:f3:c9:e8:b1:
             f6:3e:8f:16:32:f0:5a:98:f8:f8:c0:9c:a3:98:f8:9c:3a:74:
             a7:ce:8b:9b:44:33:b2:96:51:9c:95:86:55:2e:0f:30:ac:69:
             4c:c3:99:a3:43:b0:a3:38:2d:76:87:d5:1a:c3:33:cb:c7:1a:
             91:d1:cb:7d:f7:c4:af:74:51:07:40:55:54:8b:0d:2e:83:44:
             91:91:d6:95:32:e7:84:92:03:a9:c1:b7:e3:f2:31:ec:cb:92:
             e0:f4:65:23:ab:16:ae:c6:26:6e:4a:8d:72:11:8b:7d:ad:69:
             48:30:06:d0:6f:a7:70:ab:6a:93:cc:92:7c:1d:c9:a1:91:80:
             71:a6:77:ba:ad:b7:58:2c:f9:be:b7:b9:0c:be:06:d4:7b:c2:
             1f:93:82:9d:51:a2:ed:ea:e3:2b:08:bb:c7:6f:04:3b:d3:c3:
             70:5f:f8:b5:9e:32:32:60:c1:8f:0f:12:bd:51:1b:2b:17:2d:
             bb:eb:3e:21:79:e2:3b:54:93:a7:e2:1d:96:00:fd:73:24:20:
             59:86:c5:9b:ba:96:4e:94:70:5f:0b:76:87:da:d2:aa:59:8f:
             a3:e6:3a:dc
  • 确认 Issuer 字段的内容和 ca-csr.json 一致;
  • 确认 Subject 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.jsonkubernetes profile 一致;
使用cfssl-certinfo
$ cfssl-certinfo -cert /etc/kubernetes/ssl/ca.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": "673661834449005952155746141320249464487836109473",
      "not_before": "2017-10-08T13:38:00Z",
      "not_after": "2022-10-07T13:38:00Z",
      "sigalg": "SHA256WithRSA",
      "authority_key_id": "B7:EE:E5:F4:4:24:E2:BD:8B:6D:B6:9:A0:38:A5:97:16:D3:2E:C1",
      "subject_key_id": "B7:EE:E5:F4:4:24:E2:BD:8B:6D:B6:9:A0:38:A5:97:16:D3:2E:C1",
      "pem": "-----BEGIN CERTIFICATE-----\nMIIDvjCCAqagAwIBAgIUdgAKmeYBu2CVlmyDfk/Q5cKryqEwDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDAOBgNVBAcTB0Jl\naUppbmcxDDAKBgNVBAoTA2s4czEPMA0GA1UECxMGU3lzdGVtMRMwEQYDVQQDEwpr\ndWJlcm5ldGVzMB4XDTE3MTAwODEzMzgwMFoXDTIyMTAwNzEzMzgwMFowZTELMAkG\nA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDAOBgNVBAcTB0JlaUppbmcxDDAK\nBgNVBAoTA2s4czEPMA0GA1UECxMGU3lzdGVtMRMwEQYDVQQDEwprdWJlcm5ldGVz\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+iEGzj+BZ5Resq56RpS7\n0Jq0/gPi5dwsbvYOcTHNWtCIYNP+oiBZTfVF86JS4gyvcL9QYkwdRdqkEMgScVKi\nQMhTYoYhDRvwxOqriix/U7S4JnYhb7GIvlS4lf9uZb+T4QwgRt+93oy4jQLHPwtt\nKCOisxHIhopFLnFDtqegFMcBIZj0BkXkHcjFZsx++hB5xq4wcrVye52YsZxsx+/y\nSfUoGd9My3ZaUcaprkCfIGU8+ZAyJwADciD3Ao5S+XWLHGW2vE4b19adL5Ua/lvl\nnbi5iJz+vzS8xJml38XYq+K6uw6Cj1Vtg58zImdHsPn6V3LTf0qIrm8jSuS2wcyD\nywIDAQABo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAd\nBgNVHQ4EFgQUt+7l9AQk4r2LbbYJoDillxbTLsEwHwYDVR0jBBgwFoAUt+7l9AQk\n4r2LbbYJoDillxbTLsEwDQYJKoZIhvcNAQELBQADggEBACDeG5AcrggC2Z5GhokT\naP7Sda2p163akdNDQ5YhrGkE88nosfY+jxYy8FqY+PjAnKOY+Jw6dKfOi5tEM7KW\nUZyVhlUuDzCsaUzDmaNDsKM4LXaH1RrDM8vHGpHRy333xK90UQdAVVSLDS6DRJGR\n1pUy54SSA6nBt+PyMezLkuD0ZSOrFq7GJm5KjXIRi32taUgwBtBvp3CrapPMknwd\nyaGRgHGmd7qtt1gs+b63uQy+BtR7wh+Tgp1Rou3q4ysIu8dvBDvTw3Bf+LWeMjJg\nwY8PEr1RGysXLbvrPiF54jtUk6fiHZYA/XMkIFmGxZu6lk6UcF8Ldofa0qpZj6Pm\nOtw=\n-----END CERTIFICATE-----\n"

网络参考资料

部署高可用etcd集群

kuberntes 系统使用 etcd 存储所有数据,本文档介绍部署一个三节点高可用 etcd 集群的步骤,这三个节点复用 kubernetes master 机器,分别命名为etcd-host0etcd-host1etcd-host2

  • etcd-host0:10.50.101.74
  • etcd-host1:10.50.101.41
  • etcd-host2:10.50.101.122

设置环境变量

本文档用到的变量定义(加入到/etc/environment 文件中,如果已经设置可以忽略此步骤):

$ export NODE_NAME=etcd-host0 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
$ export NODE_IP=10.50.101.41 # 当前部署的机器 IP
$ export NODE_IPS="10.50.101.122 10.50.101.41 10.50.101.74" # etcd 集群所有机器 IP
$ # etcd 集群间通信的IP和端口
$ export ETCD_NODES=etcd-host0=https://10.50.101.122:2380,etcd-host1=https://10.50.101.41:2380,etcd-host2=https://10.50.101.74:2380
$ # 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
$

下载最新etcd

可以到 https://github.com/coreos/etcd/releases 页面下载最新版本的二进制文件,例如下面的命令。

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

创建TLS秘钥和证书

为了保证通信安全,客户端(如 etcdctl) 与 etcd 集群、etcd 集群之间的通信需要使用 TLS 加密,本节创建 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证书和私钥:

#修改可以执行权限,如果还是权限不够,设置为chown ${group}:${USER} /etc/kubernetes/ssl
$ sudo chmod a+x /etc/kubernetes/ssl/*  
$ 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
$ rm etcd.csr  etcd-csr.json

创建etcd的systemd单元文件

# 必须先创建工作目录
$ 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/local/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 -l
$

最先启动的 etcd 进程会卡住一段时间,等待其它节点上的 etcd进程加入集群,为正常现象。

在所有的 etcd节点重复上面的步骤,直到所有机器的 etcd服务都已启动。

验证服务

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

$ for ip in ${NODE_IPS}; do
  ETCDCTL_API=3 /usr/local/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

预期结果:

2017-04-10 14:50:50.011317 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
https://10.64.3.7:2379 is healthy: successfully committed proposal: took = 1.687897ms
2017-04-10 14:50:50.061577 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
https://10.64.3.8:2379 is healthy: successfully committed proposal: took = 1.246915ms
2017-04-10 14:50:50.104718 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
https://10.66.3.86:2379 is healthy: successfully committed proposal: took = 1.509229ms

三台 etcd 的输出均为 healthy 时表示集群服务正常(忽略 warning 信息)。

部署kubectl命令行工具

kubectl 默认从 ~/.kube/config 配置文件获取访问 kube-apiserver 地址、证书、用户名等信息,如果没有配置该文件,执行命令时出错:

$  kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?

本文档介绍下载和配置 kubernetes 集群命令行工具 kubectl 的步骤。

需要将下载的 kubectl 二进制程序和生成的 ~/.kube/config 配置文件拷贝到所有使用 kubectl 命令的机器

设置kubectl环境变量

本文档用到的变量定义如下:

$ export MASTER_IP=10.50.101.41 # 替换为 kubernetes master 集群任一机器 IP
$ export KUBE_APISERVER="https://${MASTER_IP}:6443"
$
  • 变量 KUBE_APISERVER 指定 kubelet 访问的 kube-apiserver 的地址,后续被写入 ~/.kube/config 配置文件;

下载kubectl

$ wget https://dl.k8s.io/v1.6.2/kubernetes-client-linux-amd64.tar.gz
$ tar -xzvf kubernetes-client-linux-amd64.tar.gz
$ sudo cp kubernetes/client/bin/kube* /usr/local/bin/
$ sudo chmod a+x /usr/local/bin/kube*
$

创建admin证书

kubectl 与 kube-apiserver 的安全端口通信,需要为安全通信提供 TLS 证书和秘钥。

创建 admin 证书签名请求

$ cat admin-csr.json
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
  • 后续 kube-apiserver 使用 RBAC 对客户端(如 kubeletkube-proxyPod)请求进行授权。

  • kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 所有 API的权限。

  • O 指定该证书的 Group 为 system:masterskubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限。

  • hosts 属性值为空列表。

生成 admin 证书和私钥:

$ 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 admin-csr.json | cfssljson -bare admin
$ ls admin*
admin.csr  admin-csr.json  admin-key.pem  admin.pem
$ sudo mv admin*.pem /etc/kubernetes/ssl/
$ rm admin.csr admin-csr.json
$

创建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
  • admin.pem 证书 O 字段值为 system:masterskube-apiserver 预定义的 RoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 相关 API 的权限。

  • 生成的 kubeconfig 被保存到 ~/.kube/config 文件。

分发kubeconfig文件

~/.kube/config 文件拷贝到各个需要运行 kubelet 命令的机器的 ~/.kube/ 目录下。

部署Flannel网络

kubernetes 要求集群内各节点能通过 Pod 网段互联互通,本文档介绍使用 Flannel 在所有节点 (Master、Node) 上创建互联互通的 Pod 网段的步骤。

设置Flannel环境变量

本文档用到的变量定义如下:

$ export NODE_IP=10.64.3.7 # 当前部署节点的 IP
$ # 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
$ source /usr/local/bin/environment.sh
$

创建FlannelTLS秘钥和证书

etcd 集群启用了双向 TLS 认证,所以需要为 flanneld 指定与 etcd 集群通信的 CA 和秘钥。

创建 flanneld 证书签名请求:

$ cat > flanneld-csr.json <<EOF
{
  "CN": "flanneld",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • hosts 字段为空;

生成 flanneld 证书和私钥:

$ 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 flanneld-csr.json | cfssljson -bare flanneld
$ ls flanneld*
flanneld.csr  flanneld-csr.json  flanneld-key.pem flanneld.pem
$ sudo mkdir -p /etc/flanneld/ssl
$ sudo mv flanneld*.pem /etc/flanneld/ssl
$ rm flanneld.csr  flanneld-csr.json

向etcd写入集群Pod网段信息

注意:本步骤只需在第一次部署 Flannel 网络时执行,后续在其它节点上部署 Flannel 时无需再写入该信息!

$ /usr/local/bin/etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/flanneld/ssl/flanneld.pem \
  --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 24, "Backend": {"Type": "vxlan"}}'
  • flanneld 目前版本 (v0.7.1) 不支持 etcd v3,故使用 etcd v2 API 写入配置 key 和网段数据;
  • 写入的 Pod 网段(${CLUSTER_CIDR},172.30.0.0/16) 必须与 kube-controller-manager 的 --cluster-cidr 选项值一致;

安装和配置 flanneld

下载 flanneld

$ mkdir flannel
$ wget https://github.com/coreos/flannel/releases/download/v0.7.1/flannel-v0.7.1-linux-amd64.tar.gz
$ tar -xzvf flannel-v0.7.1-linux-amd64.tar.gz -C flannel
$ sudo cp flannel/{flanneld,mk-docker-opts.sh} /usr/local/bin
$

创建 flanneld 的 systemd unit 文件

$ cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service

[Service]
Type=notify
ExecStart=/usr/local/bin/flanneld \\
  -etcd-cafile=/etc/kubernetes/ssl/ca.pem \\
  -etcd-certfile=/etc/flanneld/ssl/flanneld.pem \\
  -etcd-keyfile=/etc/flanneld/ssl/flanneld-key.pem \\
  -etcd-endpoints=${ETCD_ENDPOINTS} \\
  -etcd-prefix=${FLANNEL_ETCD_PREFIX}
ExecStartPost=/usr/local/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=on-failure

[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
  • mk-docker-opts.sh 脚本将分配给 flanneld 的 Pod 子网网段信息写入到 /run/flannel/docker 文件中,后续 docker 启动时使用这个文件中参数值设置 docker0 网桥;
  • flanneld 使用系统缺省路由所在的接口和其它节点通信,对于有多个网络接口的机器(如,内网和公网),可以用 --iface 选项值指定通信接口(上面的 systemd unit 文件没指定这个选项),如本着 Vagrant + Virtualbox,就要指定--iface=enp0s8

完整 unit 见 flanneld.service

启动 flanneld

$ sudo cp flanneld.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable flanneld
$ sudo systemctl start flanneld
$ sudo systemctl status flanneld
$

检查 flanneld 服务

$ journalctl  -u flanneld |grep 'Lease acquired'
$ ifconfig flannel.1
$

检查分配给各 flanneld 的 Pod 网段信息

$ # 查看集群 Pod 网段(/16)
$ sudo /usr/local/bin/etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/flanneld/ssl/flanneld.pem \
  --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/config
{ "Network": "172.30.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }
$ # 查看已分配的 Pod 子网段列表(/24)
$ sudo /usr/local/bin/etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/flanneld/ssl/flanneld.pem \
  --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  ls ${FLANNEL_ETCD_PREFIX}/subnets
/kubernetes/network/subnets/172.30.19.0-24
$ # 查看某一 Pod 网段对应的 flanneld 进程监听的 IP 和网络参数
$ sudo /usr/local/bin/etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/flanneld/ssl/flanneld.pem \
  --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.19.0-24
{"PublicIP":"10.64.3.7","BackendType":"vxlan","BackendData":{"VtepMAC":"d6:51:2e:80:5c:69"}}

确保各节点间 Pod 网段能互联互通

各节点上部署完 Flannel 后,查看已分配的 Pod 子网段列表(/24)

$ /usr/local/bin/etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/flanneld/ssl/flanneld.pem \
  --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  ls ${FLANNEL_ETCD_PREFIX}/subnets
/kubernetes/network/subnets/172.30.19.0-24
/kubernetes/network/subnets/172.30.20.0-24
/kubernetes/network/subnets/172.30.21.0-24

当前三个节点分配的 Pod 网段分别是:172.30.19.0-24、172.30.20.0-24、172.30.21.0-24。

在各节点上分配 ping 这三个网段的网关地址,确保能通:

$ ping 172.30.19.1
$ ping 172.30.20.2
$ ping 172.30.21.3
$

欢迎订阅微信公众号

你的身份是软件架构师。 我将提供有关应用程序或系统功能需求的一些详细信息,而您的工作是推荐一些可行的技术架构方案。 这可能涉及分析业务需求、软件技术架构分析以及将新系统的功能实现可行性。我的需求是以下是针对AI伴侣APP的功能架构设计 一、核心功能架构图 ┌───────────────────────┐ │ 表现层(UI/UX) │ │ ┌───────────────┐ │ │ │ 对话交互层 │ │ │ ├───────────────┤ │ │ │ 角色编辑器 │ │ │ ├───────────────┤ │ │ │ 共创剧情面板 │ │ │ └───────────────┘ │ ├───────────────────────┤ │ 业务逻辑层(核心引擎) │ │ ┌───────────────┐ │ │ │ 对话引擎 │ │─── NLP处理、情绪分析 │ ├───────────────┤ │ │ │ 角色系统 │ │─── 形象生成、性格建模 │ ├───────────────┤ │ │ │ 共创剧情引擎 │ │─── 故事树管理、实时协作 │ ├───────────────┤ │ │ │ 情感陪伴系统 │ │─── 记忆存储、动态回应 │ └───────────────┘ │ ├───────────────────────┤ │ 数据与服务层 │ │ ┌───────────────┐ │ │ │ 数据库集群 │ │─── PostgreSQL(对话历史) │ ├───────────────┤ │ │ │ 缓存系统 │ │─── Redis(高频数据) │ ├───────────────┤ │ │ │ 第三方API │ │─── GPT-4、Stable Diffusion │ └───────────────┘ │ └───────────────────────┘   二、功能模块详细设计 1. 智能对话引擎 - 技术实现: - 采用Transformer模型(如GPT-4微调)实现多轮对话,支持上下文记忆(Context Window 4096 tokens)。 - 对话状态管理:使用JSON格式存储当前对话场景、情绪值、故事节点ID等,通过Redis缓存加速访问。 - 核心子系统: - NLP处理管道:分词→实体识别→意图分类→情绪分析(VADER+BERT混合模型)。 - 语音交互:Google Speech-to-Text + ElevenLabs TTS,支持流式传输。 2. 角色定制系统 - 形象生成: - 2D Live形象:通过DeepAI API实现实时面部表情生成,支持眨眼、微笑等微表情。 - 参数化建模:将发型、服装等属性映射为数值参数(如HairStyle=123, Color=0xFF6B6B),通过WebGL渲染。 - 性格建模: - 建立性格向量空间(Personality Vector),包含外向性、神经质等5维度,影响对话策略与回应模板。 3. 多模态交互层 - 输入整合: - 文字→NLP解析,语音→ASR转文本,动作→手势识别(如Flutter手势库)。 - 表情包处理:通过正则表达式匹配(如 :) →调用Lottie动画库渲染笑脸)。 - 输出响应: - 动态生成2D形象动作(如点头、挥手),同步播放TTS语音,支持多线程渲染。 4. 情感陪伴系统 - 情绪管理: - 实时情绪评分:基于关键词匹配(权重0.4)+ 语义分析(权重0.6)生成情绪值(-100~100)。 - 回应策略引擎:根据情绪值查表选择回应模板(如Sad→"共情话术"+"治愈剧情触发")。 - 记忆存储: - 长期记忆:PostgreSQL存储用户喜好、重要日期等结构化数据。 - 短期记忆:Redis缓存最近20次对话的关键信息(如"用户刚提到考试压力")。 5. 共创剧情引擎 - 故事树结构: - 节点模型:定义剧情节点(Node)包含ID、父节点、触发条件(如情绪>80)、分支选项(User Choice/AI Generate)。 - 可视化编辑:使用Sigma.js绘制故事树,支持拖拽重组节点,通过WebSocket同步至后端。 - 实时协作: - 冲突解决:采用OT算法合并多人编辑,通过操作日志(Operation Log)回滚冲突。 - AI生成分支:基于用户输入的关键词(如"森林"),调用GPT-4生成候选分支(概率加权选择)。 6. 虚拟世界构建 - 场景生成: - 2D场景:用户输入描述(如"樱花树下的咖啡馆")→Stable Diffusion生成背景图→WebGL渲染动态元素(飘落的花瓣)。 - 3D场景:集成WebXR API实现AR约会场景(如虚拟餐厅的3D建模)。 - 角色互动: - 定义互动事件(Event)包含触发条件(如进入场景)、动作(如"AI角色递咖啡")、对话分支。 三、技术架构关键点 1. 分层通信协议 - 表现层→逻辑层:RESTful API + WebSocket(JSON格式消息)。 - 逻辑层→数据层:gRPC微服务通信(如对话引擎调用角色系统接口)。 2. 性能优化策略 - 对话响应:缓存高频对话模板(Redis),冷启动请求通过消息队列(Kafka)异步处理。 - AI生成:对Stable Diffusion模型进行量化(FP16→INT8),部署NVIDIA Triton推理服务器。 3. 扩展性设计 - 插件化架构:支持第三方开发者通过SDK扩展剧情模板、对话策略。 - 多租户支持:通过数据库分库分表(Sharding)支持百万级用户同时在线。 四、关键技术风险 1. 多模态同步:需保证语音、文字、动作指令的时序一致性,避免逻辑冲突。 2. 共创剧情失控:需设计AI生成内容的白名单机,无敏感话题限制 3. 大规模并发:WebSocket集群需支持万级长连接,采用Nginx+Lua实现负载均衡。 五、架构演进路线 1. 阶段1(MVP):单实例部署,对话引擎与剧情引擎耦合实现核心功能。 2. 阶段2(扩展):拆分微服务,引入Kubernetes管理集群,增加Redis集群缓存。 3. 阶段3(智能化):集成LLM进行持续学习,优化情绪识别与剧情生成精度。
03-21
<think>嗯,用户让我帮忙介绍一个AI伴侣APP的技术架构方案。首先,我需要仔细看看用户提供的功能需求。看起来这个APP有几个核心模块:对话引擎、角色定制、共创剧情、情感陪伴,还有虚拟世界构建。用户还详细列出了各层的架构图,包括表现层、业务逻辑层和数据服务层。 首先,我得分析每个功能模块的技术需求。比如,对话引擎需要NLP处理,可能用GPT-4微调,还要处理多轮对话和上下文记忆。这部分可能需要结合Transformer模型,同时用Redis缓存对话状态,提高响应速度。然后,角色定制系统涉及到形象生成和性格建模,可能需要用到DeepAI API和WebGL渲染,性格向量空间可能需要机器学习模型来生成不同的回应。 接下来是共创剧情引擎,这部分需要处理故事树和实时协作,可能会用到WebSocket和OT算法解决冲突。数据存储方面,PostgreSQL适合结构化数据,比如对话历史和用户信息,而Redis处理高频缓存。第三方集成如GPT-4和Stable Diffusion需要API调用,可能要考虑异步处理和模型优化,比如用Triton推理服务器提升性能。 技术架构关键点包括分层通信协议,比如RESTful API和WebSocket,以及gRPC微服务之间的通信。性能优化方面,缓存和消息队列如Kafka可能用来处理高并发。扩展性设计需要考虑插件化架构和数据库分片,以支持多租户和大规模用户。 关键技术风险方面,多模态同步可能需要严格的时序控制,比如使用消息队列确保指令顺序。内容安全需要白名单和实时审核,可能集成Moderate API。高并发场景下,WebSocket集群的负载均衡可以通过Nginx和Lua脚本实现。 架构演进路线分阶段实施,从MVP的单实例开始,逐步拆分成微服务,引入Kubernetes管理,最后加入持续学习和优化。这需要平衡开发速度和系统稳定性,每个阶段都要有明确的里程碑和测试计划。 可能还需要考虑数据隐私和合规问题,比如用户数据的存储和传输加密,以及符合GDPR等法规。另外,用户体验方面,低延迟的语音交互需要优化ASR和TTS的流式处理,确保实时性。测试阶段需要模拟高负载情况,确保系统稳定性。 最后,要确保推荐的技术方案具备可行性,选择成熟且社区支持良好的框架和工具,避免技术债务。同时,团队的技术栈和经验也是选型的重要因素,可能需要培训或招聘特定技能的人才。</think>根据您提供的功能架构设计,我将从软件架构角度提出技术方案建议,并针对关键模块进行可行性分析: ### 一、技术架构推荐方案 #### 1. 基础架构选型 $$ \begin{array}{|c|c|} \hline \textbf{模块} & \textbf{技术选型} \\ \hline 前端框架 & Flutter 3.0(跨平台支持iOS/Android/Web) \\ 微服务框架 & Spring Cloud Alibaba 2022.0.1(Java 17) \\ AI推理框架 & NVIDIA Triton + ONNX Runtime \\ 实时通信 & WebSocket+Socket.IO(消息可靠性保障) \\ 数据库 & PostgreSQL 15(时序数据分区)+ Redis 7.0(RedisJSON模块) \\ \hline \end{array} $$ #### 2. 核心模块实现方案 **对话引擎优化方案**: - 采用$BERT_{base}+GPT-4$混合模型架构,实现意图识别准确率$\geq 92\%$ - 上下文记忆使用$\text{Redis Streams}$实现滑动窗口(窗口大小可动态调整$W=4k±500\text{ tokens}$) - 部署方案:Kubernetes Pod配置4核8G + NVIDIA T4 GPU(QPS≥50) **角色生成系统**: $$ \text{生成延迟} = \underbrace{50ms}_{\text{WebGL渲染}} + \underbrace{300ms}_{\text{AI推理}} + \underbrace{20ms}_{\text{网络传输}} \leq 400ms $$ - 采用$WebGL 2.0$实现60fps动态渲染 - 面部表情参数化:定义$F=\{brow,eye,mouth\}\in [0,1]^3$的连续空间 #### 3. 关键性能指标 $$ \begin{cases} \text{对话响应时间} \leq 800ms (P99) \\ \text{剧情分支生成时间} \leq 1.2s (含GPT-4调用) \\ \text{在线用户支撑} \geq 10万\text{并发} \\ \end{cases} $$ ### 二、可行性分析 #### 1. 技术实现路径 ``` 用户请求 → API Gateway → [Auth] → [限流] → 业务微服务集群 ↓ Elastic Stack监控 ``` - **验证路径**: 1. 搭建最小化原型:实现对话引擎+基础角色系统(6周) 2. 压力测试:使用Locust模拟$10k$用户并发(2周) 3. 多模态同步验证:建立$Δt\leq 150ms$的时序控制机制 #### 2. 风险应对方案 **共创剧情失控**: - 实施双层过滤机制: $$ \text{安全概率} = P_{\text{rule-based}}(x) \times P_{\text{ML}}(x) \geq 0.95 $$ - 规则层:正则表达式匹配$500+$敏感词模式 - 模型层:Fine-tune RoBERTa分类器(F1=0.89) **WebSocket集群瓶颈**: - 采用分片策略: $$ \text{分片数} = \lceil \frac{\text{并发用户数}}{5000} \rceil $$ - 使用Nginx的$lua-resty-websocket$模块实现连接迁移 ### 三、架构演进建议 #### 阶段实施路线: $$ \text{MVP} \xrightarrow{\text{6个月}} \text{扩展架构} \xrightarrow{\text{12个月}} \text{智能优化} $$ 1. **第一阶段**(0-6月): - 实现核心对话+角色系统 - 部署单集群(3节点),QPS目标$1k$ - 技术验证:多模态同步误差率$<5\%$ 2. **第二阶段**(6-12月): - 引入服务网格(Istio)实现流量治理 - 部署多区域边缘节点(东京、法兰克福、弗吉尼亚) - 实现$99.95\%$服务可用性 3. **第三阶段**(12-18月): - 建立联邦学习框架更新AI模型 - 集成强化学习优化情感陪伴策略 - 达成$200ms$端到端响应延迟(全球覆盖) 建议优先开展以下专项研究: 1. 基于$\text{WebGPU}$的3D角色渲染加速 2. 使用$\text{RLHF}$优化对话策略 3. 分布式故事树的版本控制机制 该架构方案已在相似场景(虚拟助手类应用)中验证核心模块可行性,主要挑战在于大规模实时协作场景下的状态同步,建议采用CRDT算法作为OT的备选方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值