(精品)(Docker系列之十一)龙芯平台kubernetes集群编译及部署方案

timg.jpg

 
 一、环境
操作系统: loongnix
内核: 3.10.84
go版本: go1.9.2 linux/mips64le
cfssl(1.2.0)
etcd(3.2.12)
flannel(0.9.1)
kubernetes(1.9.0)
需自定义go 的环境变量,这里设置的路径为/usr/share/gocode
export GOPATH=/usr/share/gocode

三台机器:
master:10.20.42.17
node:   10.20.42.22
node:   10.20.42.172
 
二、编译cfssl源代码
1.创建代码存放目录
mkdir -p $GOPATH/src/github.com/cloudflare
2.下载并编译源代码
go get -u github.com/cloudflare/cfssl/cmd/cfssl
3.切换至二进制文件生成目录并查看文件
ls $GOPATH/bin
 
三、编译etcd源代码
参考文章(龙芯公有云系列之一)搭建分布式存储服务etcd
链接地址:http://ask.loongnix.org/?/article/93

四、编译flannel源代码
1.创建代码存放目录
 mkdir -p $GOPATH/src/github.com/coreos
2.切换至该目录并下载源代码
cd $GOPATH/src/github.com/coreos
git clone https://github.com/coreos/flannel.git
3.打开flannel文件夹,执行编译过程
cd flannel/
go build
4.查看编译的二进制文件
ls flannel
 
五、编译kubernetes源代码
Kubernetes对golang版本的要求
Kubernetes    requires Go
1.0 - 1.2         1.4.2
1.3, 1.4          1.6
1.5, 1.6          1.7 - 1.7.5
1.7                 1.8.1
1.8                 1.8.3
1.9+               1.9.1
本文档编译的Kubernetes为当前最新版本1.9.0;golang版本为1.9.2
 
Fork
1.访问 https://github.com/kubernetes/kubernetes
2.点击右上角fork按钮,fork一份代码到你的github帐号,方便后续的开发。
 
Clone fork 到本地
working_dir=$GOPATH/src/k8s.io
user=xxxx #你的github账户名
mkdir -p $working_dir
cd $working_dir
git clone https://github.com/$user/kubernetes.git
# 或: git clone git@github.com:$user/kubernetes.git

cd $working_dir/kubernetes
git remote add upstream https://github.com/kubernetes/kubernetes.git
# 或: git remote add upstream git@github.com:kubernetes/kubernetes.git

# 永远不向upstream的master分支进行push操作:
git remote set-url --push upstream no_push

# 确认你的远程配置生效
git remote -v

    origin    https://github.com/bearabby/kubernetes.git (fetch)
    origin    https://github.com/bearabby/kubernetes.git (push)
    upstream    https://github.com/kubernetes/kubernetes.git (fetch)
    upstream    no_push (push)

创建本地分支
cd $working_dir/kubernetes
git fetch upstream
git checkout master
git rebase upstream/master

git checkout -b loongsonfeature
 
Build
cd $working_dir/kubernetes
make

报错信息不多,多为一些函数或变量未对mips64le平台进行支持。修改内容见0001-Build-on-mips64le.patch
注意内存剩余不足会导致编译出错:”signal: killed”,解决办法是通过增加交换分区。
 

六、搭建kubernetes集群
1.拷贝二进制文件至/root/local/bin文件夹下
mkdir -p /root/local/bin
cp  $GOPATH/bin/cfssl  /root/local/bin 
cp  /usr/bin  /root/local/bin
cp $GOPATH/src/k8s.io/kubernetes/_output/local/go/bin/*  /root/local/bin
2.设置环境变量
export PATH=/root/local/bin:$PATH
3.设置部署集群所需参数
cd /root    /local/bin
cat > environment.sh <<EOF 
#!/usr/bin/bash
# TLS Bootstrapping 使用的 Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
BOOTSTRAP_TOKEN="6c314aea8ff601079617b03df567e478"

# 最好使用 主机未用的网段 来定义服务网段和 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)
export NODE_PORT_RANGE="8400-9000"

# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://10.20.42.17:2379,https://10.20.42.22:2379,https://10.20.42.172:2379"

# flanneld 网络配置前缀
export FLANNEL_ETCD_PREFIX="/kubernetes/network"

# kubernetes 服务 IP (一般是 SERVICE_CIDR 中第一个IP)
export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"

# 集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配)
export CLUSTER_DNS_SVC_IP="10.254.0.2"

# 集群 DNS 域名
export CLUSTER_DNS_DOMAIN="cluster.local."
EOF
 
4.创建 CA 证书和秘钥
(1)创建 CA 配置文件
 cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "8760h"
      }
    }
  }
}
EOF
参数说明:
ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;
signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
server auth:表示 client 可以用该 CA 对 server 提供的证书进行验证;
client auth:表示 server 可以用该 CA 对 client 提供的证书进行验证
(2)创建 CA 证书签名请求:
cat > ca-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048创建 CA 证书和秘钥

  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
参数说明:
"CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
"O":Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
(3)生成 CA 证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
(4)分发证书
拷贝证书到所有机器上(manager及node节点)
mkdir -p /etc/kubernetes/ssl
cp ca* /etc/kubernetes/ssl
 
5.部署高可用 etcd 集群
这三个节点复用 kubernetes master 机器,分别命名
etcd-host0:10.20.42.17
etcd-host1:10.20.42.22
etcd-host2:10.20.42.172
(1)设置etcd所需环境变量
export NODE_NAME=etcd-host0 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
export NODE_IP=10.20.42.17 # 当前部署的机器 IP
export NODE_IPS="10.20.42.17 10.20.42.22 10.20.42.172" # etcd 集群所有机器 IP
# etcd 集群间通信的IP和端口
export ETCD_NODES=etcd-host0=https://10.20.42.17:2380,etcd-host1=https://10.20.42.22:2380,etcd-host2=https://10.20.42.172:2380
# 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
source /root/local/bin/environment.sh
(2)创建 TLS 秘钥和证书
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;
(3)生成 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
mkdir -p /etc/etcd/ssl
mv etcd*.pem /etc/etcd/ssl
(4)创建 etcd 的 systemd unit 文件
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]
Environment=ETCD_UNSUPPORTED_ARCH=mips64le
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/root/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 列表中;
 
(5)启动etcd服务
mv etcd.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
在所有的 etcd 节点重复上面的步骤,直到所有机器的 etcd 服务都已启动。
(6)验证服务
部署完 etcd 集群后,在任一 etcd 集群节点上执行如下命令
for ip in ${NODE_IPS}; do
  ETCDCTL_API=3 /root/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

预期结果:
https://10.20.42.17:2379 is healthy: successfully committed proposal: took = 1.246915ms
https://10.20.42.22:2379 is healthy: successfully committed proposal: took = 1.509229ms
https://10.20.42.172:2379 is healthy: successfully committed proposal: took = 1.519269ms
三台 etcd 的输出均为 healthy 时表示集群服务正常(忽略 warning 信息)。
 
6.部署 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 命令的机器。
(1)部署 kubectl需要的变量
export MASTER_IP=10.64.3.7 
# 替换为 kubernetes master 集群任一机器 IP
export KUBE_APISERVER="https://${MASTER_IP}:6443"
说明:
变量 KUBE_APISERVER 指定 kubelet 访问的 kube-apiserver 的地址,后续被写入 ~/.kube/config 配置文件;
(2)创建 admin 证书
ubectl 与 kube-apiserver 的安全端口通信,需要为安全通信提供 TLS 证书和秘钥。
创建 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
参数说明:
后续 kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 所有 API的权限;
O 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;
hosts 属性值为空列表
(3)生成 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
mv admin*.pem /etc/kubernetes/ssl/
rm admin.csr admin-csr.json
(4)创建 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
参数说明:
admin.pem 证书 O 字段值为 system:masters,kube-apiserver 预定义的 RoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 相关 API 的权限;
生成的 kubeconfig 被保存到 ~/.kube/config 文件;
(5)分发 kubeconfig 文件
将 ~/.kube/config 文件拷贝到运行 kubelet 命令的机器的 ~/.kube/ 目录下。
 
7.部署 Flannel 网络

(1)使用的变量
export NODE_IP=10.20.42.17 # 当前部署节点的 IP
# 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
 source /root/local/bin/environment.sh
(2)创建 TLS 秘钥和证书
  创建 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
mkdir -p /etc/flanneld/ssl
mv flanneld*.pem /etc/flanneld/ssl
rm flanneld.csr  flanneld-csr.json
(3)向 etcd 写入集群 Pod 网段信息
/root/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 选项值一致;
(4)创建 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=/root/local/bin/flannel \\
  -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=/root/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
(5)启动 flanneld
 cp flanneld.service /etc/systemd/system/
 systemctl daemon-reload
 systemctl enable flanneld
 systemctl start flanneld
 
出现错误:
I1218 11:00:26.022231 11623 main.go:482] Using interface with name enp5s0 and address 10.20.42.17
I1218 11:00:26.022478 11623 main.go:499] Defaulting external address to interface address (10.20.42.17)
2017-12-18 11:00:26.027271 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
I1218 11:00:26.027501 11623 main.go:234] Created subnet manager: Etcd Local Manager with Previous Subnet: 0.0.0.0/0
I1218 11:00:26.027560 11623 main.go:237] Installing signal handlers
I1218 11:00:26.197651 11623 main.go:347] Found network config - Backend type: vxlan
I1218 11:00:26.197811 11623 vxlan.go:119] VXLAN config: VNI=1 Port=0 GBP=false DirectRouting=false
E1218 11:00:26.200720 11623 main.go:279] Error registering network: operation not supported
I1218 11:00:26.200802 11623 main.go:327] Stopping shutdownHandler...
提示内容:网络注册失败
经查找,原因为:当前loongnix系统内核版本为3.10,而vxlan的最低内核版本为3.14+,所以无法部署flannel,部署工作暂时中止
 
kubernetes源代码及编译后的二进制文件下载地址

0 个评论

要回复文章请先登录注册