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