Skip to content

Commit

Permalink
1. move admin、kubernetes、kube-proxy TLS cert to sperate chapter;
Browse files Browse the repository at this point in the history
2. create etcd、flanneld TLS cert;
3. fix typing;
  • Loading branch information
zhangjun3 committed May 7, 2017
1 parent 0b9f48a commit 1ca5680
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 240 deletions.
168 changes: 6 additions & 162 deletions 02-创建TLS证书和秘钥.md → 02-创建CA证书和秘钥.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,7 @@ tags: TLS, CA

# 创建 TLS 证书和秘钥

`kubernetes` 系统各组件需要使用 `TLS` 证书对通信进行加密,本文档使用 `CloudFlare` 的 PKI 工具集 [cfssl](https://github.com/cloudflare/cfssl) 来生成 Certificate Authority (CA) 和其它证书。

生成的 CA 证书和秘钥文件如下:

+ ca-key.pem
+ ca.pem
+ kubernetes-key.pem
+ kubernetes.pem
+ kube-proxy.pem
+ kube-proxy-key.pem
+ admin.pem
+ admin-key.pem

使用证书的组件如下:

+ etcd:使用 ca.pem、kubernetes-key.pem、kubernetes.pem;
+ kube-apiserver:使用 ca.pem、kubernetes-key.pem、kubernetes.pem;
+ kubelet:使用 ca.pem;
+ kube-proxy:使用 ca.pem、kube-proxy-key.pem、kube-proxy.pem;
+ kubectl:使用 ca.pem、admin-key.pem、admin.pem;

`kube-controller``kube-scheduler` 当前需要和 `kube-apiserver` 部署在同一台机器上且使用非安全端口通信,故不需要证书。

kubernetes 1.4 开始支持 `TLS Bootstrapping` 功能,由 `kube-apiserver` 为客户端生成 TLS 证书,这样就不需要为每个客户端生成证书(该功能**目前仅支持 `kubelet`**,所以本文档没有为 kubelet 生成证书和秘钥)。
`kubernetes` 系统各组件需要使用 `TLS` 证书对通信进行加密,本文档使用 `CloudFlare` 的 PKI 工具集 [cfssl](https://github.com/cloudflare/cfssl) 来生成 Certificate Authority (CA) 证书和秘钥文件,CA 证书用来签名后续创建的其它 TLS 证书。

## 安装 `CFSSL`

Expand Down Expand Up @@ -117,142 +94,19 @@ ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
$
```

## 创建 kubernetes 证书

创建 kubernetes 证书签名请求:

``` bash
$ cat kubernetes-csr.json
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"10.64.3.7",
"10.64.3.8",
"10.66.3.86",
"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;
+ 还需要添加 kube-apiserver 注册的名为 `kubernetes` 的服务 IP (Service Cluster IP),一般是 kube-apiserver `--service-cluster-ip-range` 选项值指定的网段的**第一个IP**,如 "10.254.0.1";

``` bash
$ kubectl get svc kubernetes
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 1d
```

生成 kubernetes 证书和私钥:

``` bash
$ 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
```
## 分发证书

或者直接在命令行上指定相关参数:
将生成的 CA 证书、秘钥文件、配置文件拷贝到**所有机器**`/etc/kubernetes/ssl` 目录下

``` bash
$ 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,10.64.3.7,10.254.0.1,kubernetes,kubernetes.default" - | cfssljson -bare kubernetes
$ sudo mkdir -p /etc/kubernetes/ssl
$ sudo cp ca* /etc/kubernetes/ssl
$
```

## 创建 admin 证书

创建 admin 证书签名请求:

``` bash
$ 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` 对客户端(如 `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 的权限;

生成 admin 证书和私钥:

``` bash
$ 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 证书签名请求:

``` bash
$ cat 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` 与 Role `system:node-proxier` 绑定,该 Role 授予了调用 `kube-apiserver` Proxy 相关 API 的权限;

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

``` bash
$ 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 证书为例
以校验 kubernetes 证书(后续部署 master 节点时生成的)为例

### 使用 `openssl` 命令

Expand Down Expand Up @@ -345,16 +199,6 @@ $ cfssl-certinfo -cert kubernetes.pem
...
```
## 分发证书
将生成的证书和秘钥文件(后缀名为`.pem`)拷贝到**所有机器**`/etc/kubernetes/ssl` 目录下:
``` bash
$ sudo mkdir -p /etc/kubernetes/ssl
$ sudo cp *.pem /etc/kubernetes/ssl
$
```
参考
+ [Generate self-signed certificates](https://coreos.com/os/docs/latest/generate-self-signed-certificates.html)
Expand Down
80 changes: 60 additions & 20 deletions 03-部署高可用Etcd集群.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,69 @@ kuberntes 系统使用 etcd 存储所有数据,本文档介绍部署一个三
$ export NODE_NAME=etcd-host0 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
$ export NODE_IP=10.64.3.7 # 当前部署的机器 IP
$ export NODE_IPS="10.64.3.7 10.64.3.8 10.66.3.86" # etcd 集群所有机器 IP
$ # etcd 集群各机器名称和对应的IP、端口
$ # etcd 集群间通信的IP和端口
$ export ETCD_NODES=etcd-host0=https://10.64.3.7:2380,etcd-host1=https://10.64.3.8:2380,etcd-host2=https://10.66.3.86:2380
$ # 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
$ source /root/local/bin/environment.sh
$
```

## TLS 认证文件
## 下载二进制文件

需要为 etcd 集群创建加密通信的 TLS 证书,这里复用以前创建的 kubernetes 证书
`https://github.com/coreos/etcd/releases` 页面下载最新版本的二进制文件

``` bash
$ sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/kubernetes/ssl
$ 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
$
```

+ kubernetes 证书的 `hosts` 字段列表中包含上面三台机器的 IP,否则后续证书校验会失败;
## 创建 TLS 秘钥和证书

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

`https://github.com/coreos/etcd/releases` 页面下载最新版本的二进制文件
创建 etcd 证书签名请求

``` bash
$ 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
$
$ 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 证书和私钥:

``` bash
$ 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 unit 文件
Expand All @@ -62,10 +100,10 @@ Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/root/local/bin/etcd \\
--name=${NODE_NAME} \\
--cert-file=/etc/kubernetes/ssl/kubernetes.pem \\
--key-file=/etc/kubernetes/ssl/kubernetes-key.pem \\
--peer-cert-file=/etc/kubernetes/ssl/kubernetes.pem \\
--peer-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \\
--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 \\
Expand All @@ -87,7 +125,6 @@ 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);
+ 创建 `kubernetes.pem` 证书时使用的 `kubernetes-csr.json` 文件的 `hosts` 字段**包含所有 etcd 节点的 NODE_IP**,否则证书校验会出错;
+ `--initial-cluster-state` 值为 `new` 时,`--name` 的参数值必须位于 `--initial-cluster` 列表中;

完整 unit 文件见:[etcd.service](https://github.com/opsnull/follow-me-install-kubernetes-cluster/blob/master/systemd/etcd.service)
Expand All @@ -103,19 +140,21 @@ $ systemctl status etcd
$
```

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

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

## 验证服务

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

``` bash
$ 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/kubernetes/ssl/kubernetes.pem \
--key=/etc/kubernetes/ssl/kubernetes-key.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem \
endpoint health; done
```

Expand All @@ -130,4 +169,5 @@ https://10.64.3.8:2379 is healthy: successfully committed proposal: took = 1.246
https://10.66.3.86:2379 is healthy: successfully committed proposal: took = 1.509229ms
```

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

46 changes: 46 additions & 0 deletions 04-部署Kubectl命令行工具.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,52 @@ $ export PATH=/root/local/bin:$PATH
$
```

## 创建 admin 证书

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

创建 admin 证书签名请求

``` bash
$ 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` 对客户端(如 `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 属性值为空列表;

生成 admin 证书和私钥:

``` bash
$ 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
$
```

## 创建 kubectl kubeconfig 文件

``` bash
Expand Down
Loading

0 comments on commit 1ca5680

Please sign in to comment.