部署 kubernetes 集群 (一)

kubernetes 集群(一)

1.组件版本和集群环境

集群组件和版本

  • Kubernetes 1.6.2
  • Docker 17.06.0-ce
  • Etcd 3.1.6
  • Flanneld 0.7.1 vxlan 网络
  • TLS 认证通信 (所有组件,如 etcd、kubernetes master 和 node)
  • RBAC 授权
  • kubelet TLS BootStrapping
  • kubedns、dashboard、heapster (influxdb、grafana)、EFK (elasticsearch、fluentd、kibana) 插件
  • 私有 docker registry,使用 ceph rgw 后端存储,TLS + HTTP Basic 认证

集群机器

  • 192.168.77.201
  • 192.168.77.202
  • 192.168.77.203

本着测试的目的,etcd 集群、kubernetes master 集群、kubernetes node 均使用这三台机器。

集群环境变量

后续的部署步骤将使用下面定义的全局环境变量,根据自己的机器、网络情况修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
NODE_NAME=etcd-host0 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
NODE_IP="192.168.77.201" # 当前部署的机器 IP
NODE_IPS="192.168.77.201 192.168.77.202 192.168.77.203" # etcd 集群所有机器 IP
# etcd 集群间通信的IP和端口
export ETCD_NODES=etcd-host0=https://192.168.77.201:2380,etcd-host1=192.168.77.202:2380,etcd-host2=https://192.168.77.203:2380

# 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
# TLS Bootstrapping 使用的 Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
BOOTSTRAP_TOKEN="5dedacd78457d0511e20e8b0832fc3bc"

# 建议用 未用的网段 来定义服务网段和 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="8400-9000"

# etcd 集群服务地址列表
ETCD_ENDPOINTS="https://192.168.77.201:2379,https://192.168.77.202:2379,https://192.168.77.203: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."

# 替换为 kubernetes master 集群任一机器 IP
MASTER_IP="192.168.77.201"
KUBE_APISERVER="https://${MASTER_IP}:6443"
  • 打包后的变量定义见 environment.sh,后续部署时会提示导入该脚本;

分发集群环境变量定义脚本

把全局变量定义脚本拷贝到所有机器的 /root/local/bin 目录:

1
cp environment.sh /root/local/bin

2.创建CA证书和秘钥

创建 CA 证书和秘钥

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

安装 CFSSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
chmod +x cfssl_linux-amd64
sudo mv cfssl_linux-amd64 /root/local/bin/cfssl

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

wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /root/local/bin/cfssl-certinfo
vim /etc/profile
export PATH=/root/local/bin:$PATH
mkdir ssl
cd ssl
cfssl print-defaults config > config.json
cfssl print-defaults csr > csr.json

创建 CA (Certificate Authority)

创建 CA 配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
vim 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 证书签名请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ 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 证书和私钥:

1
2
3
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 目录下

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

创建 kubernetes 证书签名请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ cat kubernetes-csr.json
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.77.201",
"192.168.77.202",
"192.168.77.203",
"10.254.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": "System"
}
]
}
  • 如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了 etcd 集群、kubernetes master 集群的主机 IP 和 kubernetes 服务的服务 IP(一般是 kue-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1。

生成 kubernetes 证书和私钥

1
2
3
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
$ ls kubernetes*
kubernetes.csr kubernetes-csr.json kubernetes-key.pem kubernetes.pem

或者直接在命令行上指定相关参数:

1
$ echo '{"CN":"kubernetes","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes -hostname="127.0.0.1,192.168.77.201,192.168.77.202,192.168.77.203,10.254.0.1,kubernetes,kubernetes.default" - | cfssljson -bare kubernetes

创建 Admin 证书

创建 admin 证书签名请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vim 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 将 Groupsystem:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver所有 API的权限;
  • OU 指定该证书的 Group 为 system:masterskubelet 使用该证书访问 kube-apiserver时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的system:masters,所以被授予访问所有 API 的权限;

生成 admin 证书和私钥

1
2
3
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
ls admin*
admin.csr admin-csr.json admin-key.pem admin.pem

创建 Kube-Proxy 证书

创建 kube-proxy 证书签名请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vim kube-proxy-csr.json
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
  • CN 指定该证书的 User 为 system:kube-proxy
  • kube-apiserver 预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Rolesystem:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

生成 kube-proxy 客户端证书和私钥

1
2
3
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy
ls kube-proxy*
kube-proxy.csr kube-proxy-csr.json kube-proxy-key.pem kube-proxy.pem

校验证书

以 kubernetes 证书为例

使用 Opsnssl 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
openssl x509  -noout -text -in  kubernetes.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
cc:f1:04:70:82:fb:9e:80:38:8d:9e:2a:a2:d6:c1:1d:b5:85:0a
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=kubernetes
Validity
Not Before: Jul 6 03:05:00 2017 GMT
Not After : Jul 6 03:05:00 2018 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:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
B3:F3:E3:4C:AD:86:FD:FE:5D:B5:E1:26:94:D3:E2:4C:AE:50:5B:C3
X509v3 Authority Key Identifier:
keyid:5D:A9:C1:8C:C3:1D:58:A8:6C:7B:C9:08:1D:3F:09:D3:CA:2B:F8:92

X509v3 Subject Alternative Name:
DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.default.svc.cluster.local, IP Address:127.0.0.1, IP Address:192.168.77.201, IP Address:192.168.77.202, IP Address:192.168.77.203, IP Address:10.254.0.1
...
  • 确认 Issuer 字段的内容和 ca-csr.json 一致;
  • 确认 Subject 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.jsonkubernetesprofile 一致

使用 Cfssl-Certinfo 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
cfssl-certinfo -cert kubernetes.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": "4570347592092906586131725795238401977456362762",
"sans": [
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"127.0.0.1",
"192.168.77.201",
"192.168.77.202",
"192.168.77.203",
"10.254.0.1"
],
"not_before": "2017-07-06T03:05:00Z",
"not_after": "2018-07-06T03:05:00Z",
"sigalg": "SHA256WithRSA",
...

分发证书

将生成的证书和秘钥文件(后缀名为.pem)拷贝到所有机器的 /etc/kubernetes/ssl 目录下备用;

1
2
3
4
mkdir -p /etc/kubernetes/ssl
cp *.pem /etc/kubernetes/ssl
scp *.pem root@node2:/etc/kubernetes/ssl
scp *.pem root@node3:/etc/kubernetes/ssl

3.部署高可用 etcd 集群

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

  • etcd-host0:192.168.77.201
  • etcd-host1:192.168.77.201
  • etcd-host2:192.168.77.201

使用的变量

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

1
2
3
4
5
6
export NODE_NAME=etcd-host0 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
export NODE_IP=192.168.77.201 # 当前部署的机器 IP
export NODE_IPS="192.168.77.201 192.168.77.202 192.168.77.203" # etcd 集群所有机器 IP
export ETCD_NODES=etcd-host0=https://192.168.77.201:2380,etcd-host1=https://192.168.77.202:2380,etcd-host2=https://192.168.77.203:2380 #etcd 集群间通信的IP和端口
export ETCDCTL_API=3 #flannel暂时不支持etcd3
source /root/local/bin/environment.sh #导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR

下载二进制文件

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

1
2
3
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* /root/local/bin

创建 TLS 秘钥和证书

为了保证通信安全,客户端(如 etcdctl) 与 etcd 集群、etcd 集群之间的通信需要使用 TLS 加密,本节创建 etcd TLS 加密所需的证书和私钥。

创建 etcd 证书签名请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vim etcd-csr.json
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.77.201",
"192.168.77.202",
"192.168.77.203"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
  • hosts 字段指定授权使用该证书的 etcd 节点 IP;

生成 etcd 证书和私钥:

1
2
3
4
5
6
7
8
9
10
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
mkdir -p /etc/etcd/ssl
cp etcd*.pem /etc/etcd/ssl
scp etcd*.pem root@node2:/etc/etcd/ssl
scp etcd*.pem root@node3:/etc/etcd/ssl

创建 etcd 的 systemd unit 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
mkdir -p /var/lib/etcd  # 必须先创建工作目录
vim /lib/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=/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

上面的的读取环境变量的有些问题,暂时还没有处理用以下使用绝对配置没有问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[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/
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/root/local/bin/etcd \
--name=etcd-host0 \
--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://192.168.77.201:2380 \
--listen-peer-urls=https://192.168.77.201:2380 \
--listen-client-urls=https://192.168.77.201:2379,http://127.0.0.1:2379 \
--advertise-client-urls=https://192.168.77.201:2379 \
--initial-cluster-token=etcd-cluster-0 \
--initial-cluster=etcd-host0=https://192.168.77.201:2380,etcd-host1=https://192.168.77.202:2380,etcd-host2=https://192.168.77.203:2380 \
--initial-cluster-state=new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

上面的etcd.service需要复制到集群的2台node节点,除了–initial-cluster不需要动,–name=etcd-host0修改为对应的节点名,可以不是hostname,其他参数需要修改成当前节点的ip;

  • 指定 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 列表中;

完整 unit 文件见:etcd.service

启动 etcd 服务

1
2
3
4
5
cp etcd.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl status etcd

最先启动的 etcd 进程会卡住一段时间,等待其它节点上的 etcd 进程加入集群,为正常现象。
另外,注意的是,需要修改的相关参数
在所有的 etcd 节点重复上面的步骤,直到所有机器的 etcd 服务都已启动。

如果有防火墙,需要开放2379,2380
firewall-cmd --permanent --zone=public --add-port=2379/tcp
firewall-cmd --permanent --zone=public --add-port=2380/tcp

验证服务

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

1
2
3
4
5
6
7
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

返回以下信息就成功了

1
2
3
4
5
6
2017-07-06 11:49:21.473944 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
https://192.168.77.201:2379 is healthy: successfully committed proposal: took = 1.618919ms
2017-07-06 11:49:21.510179 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
https://192.168.77.202:2379 is healthy: successfully committed proposal: took = 1.718529ms
2017-07-06 11:49:21.544829 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
https://192.168.77.203:2379 is healthy: successfully committed proposal: took = 1.99899ms

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

4.部署 kubectl 命令行工具

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

1
2
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
2
3
# 替换为 kubernetes maste 集群任一机器 IP
export MASTER_IP=192.168.77.201
export KUBE_APISERVER="https://${MASTER_IP}:6443"
  • 变量 KUBE_APISERVER 指定 kubelet 访问的 kube-apiserver 的地址,后续被写入 ~/.kube/config 配置文件;

下载 kubectl

1
2
3
4
5
wget https://dl.k8s.io/v1.6.2/kubernetes-client-linux-amd64.tar.gz
tar -xzvf kubernetes-client-linux-amd64.tar.gz
cp kubernetes/client/bin/kube* /root/local/bin/
chmod a+x /root/local/bin/kube*
export PATH=/root/local/bin:$PATH

创建-admin-证书

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

创建 admin 证书签名请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vim 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 证书和私钥:

1
2
3
4
5
6
7
8
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
cp admin*.pem /etc/kubernetes/ssl/
rm admin.csr admin-csr.json

创建 kubectl kubeconfig 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 设置集群参数
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/ 目录下。

待续