## ** 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
```