## ** Ubuntu物理节点上部署Kubernets集群**
**前提条件**
kubernetes的完整部署大概涉及到如下几个方面:
* master节点的集群方案
* pod的网络方案
* dns方案
* 日志收集方案
* 容器对外暴露的负载均衡方案
* 容器监控方案
至于dns方案,我这里直接采用coredns,然而在我们实际生产部署中,并没有将coredns通过service的方式部署到kubernetes中,而是独立部署coredns,并将kubernetes作为其后端,这篇文档并不对coredns做展开说明,只是演示coredns部署到kubernetes中的方法,仍以service方式将其部署至kubernetes中。独立部署的方式会单独在后续文档中再作说明。
另外还需要说明,因为centos上docker的devicemapper性能问题,我这里使用的操作系统是ubuntu 16.04。生产环境也建议使用ubuntu系统。
**# 环境说明**
| 主机IP | 主机名 | 基础组件 |
---|--- |---
192.168.11.212 |master1 |kube-apiserver/kube-scheduler/kube-controller-manager/etcd/coredns
192.168.11.213 |master2 |kube-apiserver/kube-scheduler/kube-controller-manager/etcd
192.168.11.214 |master3 |kube-apiserver/kube-scheduler/kube-controller-manager/etcd
192.168.11.220 |node1 |docker-ce/ kubelet /kube-proxy/quagga
192.168.11.221 |node2 |docker-ce/ kubelet /kube-proxy/quagga
192.168.11.222 |node3 |docker-ce/ kubelet /kube-proxy/quagga
192.168.11.217 |a1 |harbor
192.168.11.219 |a2 |jenkins-master
192.168.11.215 |a3 |haproxy/keepalived/jenkins-slave_1
192.168.11.216 |a4 |haproxy/keepalived/jenkins-slave_2
192.168.11.223 |efk1 |zookeeper/kafka
192.168.11.224 |efk2 |zookeeper/kafka
192.168.11.225 |efk3 |zookeeper/kafka
192.168.11.231 |elk1 |logstash/elasticsearch/kibana
192.168.11.232 |elk2 |logstash/elasticsearch/kibana
192.168.11.233 |elk3 |logstash/elasticsearch/kibana
**# 安装前的约定**
我们创建/opt/kubernetes作为安装目录,所有的证书文件都会存放在/opt/kubernetes/ssl目录下;所有的配置文件,包括etcd.conf, bootstrap.kubeconfig等都存放在/opt/kubernetes/cfg目录下;所有可执行文件,包括etcd,etcdctl, kube-apiserver, kubelet, kube-proxy, kube-controlelr-manager, kube-scheduler, cfssl, cfssljosn等都存放在/opt/kubernetes/bin目录下;所有日志会存放在/opt/kubernetes/log目录下;
创建安装目录如下:
```
mkdir -p /opt/kubernetes/{bin,ssl,cfg,log}
```
**# 生成相关证书**
**## 证书类型说明**
证书名称 | 配置文件 | 用途
---|--- |---
ca.pem | ca-csr.json | ca根证书
kube-proxy.pem | ca-config.json kube-proxy-csr.json| kube-proxy使用的证书
admin.pem | admin-csr.json ca-config.json | kubectl 使用的证书
kubernetes.pem | ca-config.json kubernetes-csr.json| apiserver使用的证书
**## cfssl配置**
```
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /opt/kubernetes/bin/cfssl
mv cfssljson_linux-amd64 /opt/kubernetes/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /opt/kubernetes/bin/cfssl-certinfo
```
**### 生成ca证书**
ca-config.json文件内容如下:
```sh
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "175200h"
},
"profiles": {
"kubernetes": {
"expiry": "175200h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"etcd": {
"expiry": "175200h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
```
字段说明:
* ca-config.json:可以定义多个Profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书的时候使用某个Profile。这里定义了两个Profile,一个用于kubernetes,一个用于etcd,我这里etcd没有使用证书,所以另一个不使用。
* signing:表示该 证书可用于签名其他证书;生成的ca.pem证书中CA=TRUE
* server auth:表示client可以使用该ca对server提供的证书进行验证
* client auth:表示server可以用该ca对client提供的证书进行验证
ca-csr.json内容如下:
```
cat > ca-csr.json << EOF
{
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Wuhan",
"ST": "Hubei",
"O": "k8s",
"OU": "System"
}
]
}
EOF
```
生成ca证书:
```
cfssl gencert --initca=true ca-csr.json | cfssljson --bare ca
```
### 生成kubernetes证书
kubernetes-csr.json内容如下:
```sh
cat > kubernetes-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"localhost",
"192.168.11.212",
"192.168.11.213",
"192.168.11.214",
"192.168.11.215",
"192.168.11.216",
"192.168.11.230",
"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": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "System"
}
]
}
EOF
```
这个内容需要做下简要说明:
上面配置hosts字段中指定授权使用该证书的IP和域名列表,因为现在要生成的证书需要被Kubernetes Master集群各个节点使用,所以这里指定了各个节点的IP和hostname。
生成kubernetes证书:
```
cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config.json --profile kubernetes kubernetes-csr.json | cfssljson --bare kubernetes
```
**### 生成kubectl证书**
admin-csr.json内容如下:
```
cat > admin-csr.json << EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
```
生成kubectl证书:
```
cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config.json --profile kubernetes admin-csr.json | cfssljson --bare admin
```
**### 生成kube-proxy证书**
kube-proxy-csr.json内容如下:
```
cat > kube-proxy-csr.json << EOF
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "System"
}
]
}
EOF
```
* 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证书:
```
cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config.json --profile kubernetes kube-proxy-csr.json | cfssljson --bare kube-proxy
```
**### 创建Token kubeconfig文件**
请先参考 安装kubectl命令行工具,先在 master 节点上安装 kubectl 然后再进行下面的操作。kubelet、kube-proxy 等 Node 机器上的进程与 Master 机器的 kube-apiserver 进程通信时需要认证和授权
以下操作只需要在master节点上执行,生成的*.kubeconfig文件可以直接拷贝到node节点的/opt/kubernetes/cfg目录下
下载kubernetes server包,包含所有组建和工具,拷贝kubectl至/opt/kubernetes/bin
# https://github.com/kubernetes/kubernetes/releases(下载地址)
```
添加环境变量
# vim /root/.bash_profile
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
# source /root/.bash_profile
创建 TLS Bootstrapping Token
# cd /opt/kubernetes/ssl/
# export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
# cat > token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
```
**## 生成bashboard使用的http basic认证文件**
```
cat > basic_auth.csv <<EOF
123456,admin,1,"system:masters"
EOF
```
## 生成kubeconfig
```
keepalived :### export KUBE_APISERVER="https://192.168.11.230:6443"
# 设置集群参数,即api-server的访问方式,给集群起个名字就叫kubernetes
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
# 设置客户端认证参数,这里采用token认证
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=bootstrap.kubeconfig
# 设置上下文参数,用于连接用户kubelet-bootstrap与集群kubernetes
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
# 设置默认上下文
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
```
kube-proxy的kubeconfig配置如下,与上面基本相同:
```
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials kube-proxy \
--client-certificate=kube-proxy.pem \
--client-key=kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
# 设置上下文参数
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
# 设置默认上下文
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
```