项目致力于让有意向使用原生kubernetes集群的企业或我的,能够方便的、系统的使用二进制的方式手工搭建kubernetes高可用集群。而且让相关的人员能够更好的理解kubernetes集群的运做机制。node
kube-apiserver:linux
kube-controller-manager:nginx
kube-scheduler:git
kubelet:github
kube-proxy:web
集群插件:docker
咱们这里使用的是五台centos 7.7虚拟机,具体信息以下表:json
系统类型 | IP地址 | 节点角色 | CPU | Memory | Hostname |
---|---|---|---|---|---|
centos-7.7 | 172.18.0.100 | master | >=2 | >=2G | k8s-m01 |
centos-7.7 | 172.18.0.101 | master | >=2 | >=2G | k8s-m02 |
centos-7.7 | 172.18.0.102 | master | >=2 | >=2G | k8s-m03 |
centos-7.7 | 172.18.0.103 | worker | >=2 | >=2G | k8s-n01 |
centos-7.7 | 172.18.0.104 | worker | >=2 | >=2G | k8s-n02 |
主机名必须每一个节点都不同,而且保证全部点之间能够经过 hostname 互相访问。bootstrap
# 查看主机名 $ hostname # 修改主机名 $ hostnamectl set-hostname <your_hostname> # 配置host,使主节点之间能够经过hostname互相访问 $ vi /etc/hosts # <node-ip> <node-hostname>
# 更新yum $ yum update # 安装依赖包 $ yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp wget ## 时间同步 $ ntpdate time1.aliyun.com
# 关闭防火墙 $ systemctl stop firewalld && systemctl disable firewalld # 重置iptables $ iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT # 关闭swap $ swapoff -a $ sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab # 关闭selinux $ setenforce 0 # 关闭dnsmasq(不然可能致使docker容器没法解析域名) $ service dnsmasq stop && systemctl disable dnsmasq
# 制做配置文件 $ cat > /etc/sysctl.d/kubernetes.conf <<EOF net.bridge.bridge-nf-call-iptables=1 net.bridge.bridge-nf-call-ip6tables=1 net.ipv4.ip_forward=1 vm.swappiness=0 vm.overcommit_memory=1 vm.panic_on_oom=0 fs.inotify.max_user_watches=89100 EOF # 生效文件 $ sysctl -p /etc/sysctl.d/kubernetes.conf
modprobe ip_vs_rr modprobe br_netfilter
根据kubernetes对docker版本的兼容测试状况,咱们选择18.06版本,咱们配置阿里云的源,速度比较快。ubuntu
# 添加 yum 源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -P /etc/yum.repos.d/ # 清理原有版本 yum remove -y docker* container-selinux # 安装docker yum list docker-ce.x86_64 --showduplicates |sort -r yum install docker-ce-18.06.1.ce -y # 开机启动 systemctl enable docker # 配置加速器 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://hdi5v8p1.mirror.aliyuncs.com"] } EOF # 启动docker服务 service docker restart
为了方便文件的copy咱们选择一个中转节点(随便一个节点,能够是集群中的也能够是非集群中的),配置好跟其余全部节点的免密登陆,咱们这里使用 k8s-m01。
# 看看是否已经存在rsa公钥 $ cat ~/.ssh/id_rsa.pub # 若是不存在就建立一个新的 $ ssh-keygen -t rsa # 免密钥认证 $ ssh-copy-id root@<your-server-ip>
官方下载地址(在CHANGELOG连接里面):
https://github.com/kubernetes/kubernetes/releases
咱们选择的版本是 1.16.2
。
网盘下载地址--推荐(我从官网下载整理好的文件):
连接: https://pan.baidu.com/s/1Ut9VERgm55B4lmz0wjjzFQ
提取码: mjem
# 把文件copy到每一个节点上(注意替换本身的文件目录) $ scp master/* <user>@<master-ip>:/usr/local/bin/ $ scp worker/* <user>@<worker-ip>:/usr/local/bin/ # 给文件添加可执行权限 $ chmod +x /usr/local/bin/*
上一步咱们下载了kubernetes各个组件的二进制文件,这些可执行文件的运行也是须要添加不少参数的,包括有的还会依赖一些配置文件。如今咱们就把运行它们须要的参数和配置文件都准备好。
我这准备了一个项目,专门为你们按照本身的环境生成配置的。它只是帮助你们尽可能的减小了机械化的重复工做。它并不会帮你设置系统环境,不会给你安装软件。总之就是会减小你的部署工做量,但不会耽误你对整个系统的认识和把控。
$ cd ~ $ git clone https://github.com/wangzan18/kubernetes-ha-binary.git # 看看git内容 $ ls -l kubernetes-ha-binary addons/ configs/ pki/ services/ init.sh global-configs.properties
addons :kubernetes的插件目录,包括calico、coredns、dashboard等。
configs:这个目录比较 - 凌乱,包含了部署集群过程当中用到的杂七杂八的配置文件、脚本文件等。
pki:各个组件的认证受权相关证书配置。
services:全部的kubernetes服务(service)配置文件。
global-configs.properties:全局配置,包含各类易变的配置内容。
init.sh:初始化脚本,配置好global-config以后,会自动生成全部配置文件。
这里会根据你们各自的环境生成kubernetes部署过程须要的配置文件。
在每一个节点上都生成一遍,把全部配置都生成好,后面会根据节点类型去使用相关的配置。
# cd到以前下载的git代码目录 $ cd kubernetes-ha-binary # 编辑属性配置(根据文件注释中的说明填写好每一个key-value) $ vim global-config.properties # 生成配置文件,确保执行过程没有异常信息 $ ./init.sh # 查看生成的配置文件,确保脚本执行成功 $ find target/ -type f
cfssl是很是好用的CA工具,咱们用它来生成证书和秘钥文件
安装过程比较简单,以下:
# 下载 $ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl $ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson # 修改成可执行权限 $ chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson # 验证 $ cfssl version Version: 1.2.0 Revision: dev Runtime: go1.6
查看证书配置文件,CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过时时间、服务端认证、客户端认证、加密等),后续在签名其它证书时须要指定特定场景。
$ cd target/pki/ $ cat ca-config.json { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "87600h" } } } }
signing
:表示该证书可用于签名其它证书,生成的 ca.pem
证书中 CA=TRUE
;server auth
:表示 client 能够用该该证书对 server 提供的证书进行验证;client auth
:表示 server 能够用该该证书对 client 提供的证书进行验证;查看证书签名请求文件。
$ cat ca-csr.json { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "seven" } ] }
Common Name
,kube-apiserver 从证书中提取该字段做为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;Organization
,kube-apiserver 从证书中提取该字段做为请求用户所属的组 (Group);RBAC
受权的用户标识;根证书是集群全部节点共享的,只须要建立一个 CA 证书,后续建立的全部证书都由它签名。
# 生成证书和私钥 $ cd target/pki $ cfssl gencert -initca ca-csr.json | cfssljson -bare ca # 生成完成后会有如下文件(咱们最终想要的就是ca-key.pem和ca.pem,一个秘钥,一个证书) $ ls ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem # 建立目录 $ ssh <user>@<node-ip> "mkdir -p /etc/kubernetes/pki/" # 分发到每一个matser主节点 $ scp ca*.pem <user>@<master-ip>:/etc/kubernetes/pki/
$ wget https://github.com/etcd-io/etcd/releases/download/v3.4.3/etcd-v3.4.3-linux-amd64.tar.gz $ tar xf etcd-v3.4.3-linux-amd64.tar.gz $ scp etcd-v3.4.3-linux-amd64/etcd* <user>@<master-ip>:/usr/local/bin/
查看证书请求文件。
$ cd target/pki/etcd $ cat etcd-csr.json { "CN": "etcd", "hosts": [ "127.0.0.1", "172.18.0.100", "172.18.0.101", "172.18.0.102" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "seven" } ] }
# 生成证书、私钥 $ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes etcd-csr.json | cfssljson -bare etcd # 分发到每一个etcd节点(master节点) $ scp etcd*.pem <user>@<master-ip>:/etc/kubernetes/pki/
# scp配置文件到每一个master节点 $ scp target/<node-ip>/services/etcd.service <node-ip>:/etc/systemd/system/ # 建立数据和工做目录 $ ssh <user>@<node-ip> "mkdir -p /var/lib/etcd"
etcd 进程首次启动时会等待其它节点的 etcd 加入集群,命令 systemctl start etcd 会卡住一段时间,为正常现象。
#启动服务 $ systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd #查看状态 $ service etcd status #查看启动日志 $ journalctl -f -u etcd #查看服务监听端口 $ netstat -tlnp |grep etcd
查看证书请求文件。
$ cd target/pki/apiserver $ cat kubernetes-csr.json { "CN": "kubernetes", "hosts": [ "127.0.0.1", "172.18.0.100", "172.18.0.101", "172.18.0.102", "172.18.0.88", "10.96.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": "seven" } ] }
# 生成证书、私钥 $ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes # 分发到每一个master节点 $ scp kubernetes*.pem <user>@<master-ip>:/etc/kubernetes/pki/
建立证书签名请求:
$ cd target/pki/metrics-server $ cat > proxy-client-csr.json <<EOF { "CN": "aggregator", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "seven" } ] } EOF
--requestheader-allowed-names
参数中,不然后续访问 metrics 时会提示权限不足。生成证书和私钥:
$ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes proxy-client-csr.json | cfssljson -bare proxy-client # 分发到每一个master节点 $ scp proxy-client*.pem <user>@<master-ip>:/etc/kubernetes/pki/
# scp配置文件到每一个master节点 $ scp target/<node-ip>/services/kube-apiserver.service <user>@<node-ip>:/etc/systemd/system/ # 建立日志目录 $ ssh <user>@<node-ip> "mkdir -p /var/log/kubernetes" # 复制配置文件 $ scp target/configs/encryption-config.yaml <user>@<master-ip>:/etc/kubernetes/ $ scp target/configs/audit-policy.yaml <user>@<master-ip>:/etc/kubernetes/
#启动服务 $ systemctl daemon-reload && systemctl enable kube-apiserver && systemctl restart kube-apiserver #查看运行状态 $ service kube-apiserver status #查看日志 $ journalctl -f -u kube-apiserver #检查监听端口 $ netstat -ntlp|grep kube-apiserver
可使用 nginx 作负载均衡器,把请求分发到后面三台apiserver服务器上面,这样最好,也是官方推荐的。
# 在两个主节点上安装keepalived(一主一备),我这里选择 k8s-m01, k8s-m02 $ yum install -y keepalived
# 建立目录 $ ssh <user>@<master-ip> "mkdir -p /etc/keepalived" $ ssh <user>@<backup-ip> "mkdir -p /etc/keepalived" # 分发配置文件 $ scp target/configs/keepalived-master.conf <user>@<master-ip>:/etc/keepalived/keepalived.conf $ scp target/configs/keepalived-backup.conf <user>@<backup-ip>:/etc/keepalived/keepalived.conf # 分发监测脚本 $ scp target/configs/check-apiserver.sh <user>@<master-ip>:/etc/keepalived/ $ scp target/configs/check-apiserver.sh <user>@<backup-ip>:/etc/keepalived/
# 分别在master和backup上启动服务 $ systemctl enable keepalived && service keepalived start # 检查状态 $ service keepalived status # 查看日志 $ journalctl -f -u keepalived # 访问测试 $ curl --insecure https://<master-vip>:6443/ { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }
kubectl 是 kubernetes 集群的命令行管理工具,它默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息。
kubectl 与 apiserver https 安全端口通讯,apiserver 对提供的证书进行认证和受权。
kubectl 做为集群的管理工具,须要被授予最高权限。这里建立具备最高权限的 admin 证书。
$ cd target/pki/admin $ cat admin-csr.json { "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:masters", "OU": "seven" } ] }
system:masters
,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters;cluster-admin
将 Group system:masters
与 Role cluster-admin
绑定,该 Role 授予全部 API的权限;# 建立证书、私钥 $ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes admin-csr.json | cfssljson -bare admin
kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的全部信息,如 apiserver 地址、CA 证书和自身使用的证书
# 设置集群参数 $ kubectl config set-cluster kubernetes \ --certificate-authority=../ca.pem \ --embed-certs=true \ --server=https://<MASTER_VIP>:6443 \ --kubeconfig=kube.config # 设置客户端认证参数 $ kubectl config set-credentials admin \ --client-certificate=admin.pem \ --client-key=admin-key.pem \ --embed-certs=true \ --kubeconfig=kube.config # 设置上下文参数 $ kubectl config set-context admin@kubernetes \ --cluster=kubernetes \ --user=admin \ --kubeconfig=kube.config # 设置默认上下文 $ kubectl config use-context admin@kubernetes --kubeconfig=kube.config # 分发到目标节点 $ scp kube.config <user>@<node-ip>:~/.kube/config
--certificate-authority
:验证 kube-apiserver 证书的根证书;--client-certificate
、--client-key
:刚生成的 admin
证书和私钥,链接 kube-apiserver 时使用;--embed-certs=true
:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(不加时,写入的是证书文件路径,后续拷贝 kubeconfig 到其它机器时,还须要单独拷贝证书文件,不方便。);在执行 kubectl exec、run、logs 等命令时,apiserver 会转发到 kubelet。这里定义 RBAC 规则,受权 apiserver 调用 kubelet API。
$ kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
# 查看集群信息 $ kubectl cluster-info $ kubectl get all -A $ kubectl get cs
controller-manager启动后将经过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。
查看证书请求。
$ cd target/pki/controller-manager $ cat controller-manager-csr.json { "CN": "system:kube-controller-manager", "key": { "algo": "rsa", "size": 2048 }, "hosts": [ "127.0.0.1", "172.18.0.100", "172.18.0.101", "172.18.0.102" ], "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:kube-controller-manager", "OU": "seven" } ] }
system:kube-controller-manager
,kubernetes 内置的 ClusterRoleBindings system:kube-controller-manager
赋予 kube-controller-manager 工做所需的权限。# 生成证书、私钥 $ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes controller-manager-csr.json | cfssljson -bare controller-manager # 分发到每一个master节点 $ scp controller-manager*.pem <user>@<node-ip>:/etc/kubernetes/pki/
# 建立kubeconfig $ kubectl config set-cluster kubernetes \ --certificate-authority=../ca.pem \ --embed-certs=true \ --server=https://<MASTER_VIP>:6443 \ --kubeconfig=controller-manager.kubeconfig $ kubectl config set-credentials system:kube-controller-manager \ --client-certificate=controller-manager.pem \ --client-key=controller-manager-key.pem \ --embed-certs=true \ --kubeconfig=controller-manager.kubeconfig $ kubectl config set-context system:kube-controller-manager@kubernetes \ --cluster=kubernetes \ --user=system:kube-controller-manager \ --kubeconfig=controller-manager.kubeconfig $ kubectl config use-context system:kube-controller-manager@kubernetes --kubeconfig=controller-manager.kubeconfig # 分发controller-manager.kubeconfig $ scp controller-manager.kubeconfig <user>@<node-ip>:/etc/kubernetes/
# scp配置文件到每一个master节点 $ scp target/<node-ip>/services/kube-controller-manager.service <user>@<node-ip>:/etc/systemd/system/
# 启动服务 $ systemctl daemon-reload && systemctl enable kube-controller-manager && systemctl restart kube-controller-manager # 检查状态 $ service kube-controller-manager status # 查看日志 $ journalctl -f -u kube-controller-manager # 查看leader $ kubectl get endpoints kube-controller-manager --namespace=kube-system -o yaml
scheduler启动后将经过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。
查看证书请求文件。
$ cd target/pki/scheduler $ cat scheduler-csr.json { "CN": "system:kube-scheduler", "hosts": [ "127.0.0.1", "172.18.0.100", "172.18.0.101", "172.18.0.102" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:kube-scheduler", "OU": "seven" } ] }
system:kube-scheduler
,kubernetes 内置的 ClusterRoleBindings system:kube-scheduler
将赋予 kube-scheduler 工做所需的权限;# 生成证书、私钥 $ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes scheduler-csr.json | cfssljson -bare kube-scheduler # 分发到每一个master节点 $ scp kube-scheduler*.pem <user>@<node-ip>:/etc/kubernetes/pki/
# 建立kubeconfig $ kubectl config set-cluster kubernetes \ --certificate-authority=../ca.pem \ --embed-certs=true \ --server=https://<MASTER_VIP>:6443 \ --kubeconfig=kube-scheduler.kubeconfig $ kubectl config set-credentials system:kube-scheduler \ --client-certificate=kube-scheduler.pem \ --client-key=kube-scheduler-key.pem \ --embed-certs=true \ --kubeconfig=kube-scheduler.kubeconfig $ kubectl config set-context system:kube-scheduler@kubernetes \ --cluster=kubernetes \ --user=system:kube-scheduler \ --kubeconfig=kube-scheduler.kubeconfig $ kubectl config use-context system:kube-scheduler@kubernetes --kubeconfig=kube-scheduler.kubeconfig # 分发kubeconfig $ scp kube-scheduler.kubeconfig <user>@<node-ip>:/etc/kubernetes/
# scp配置文件到每一个master节点 $ scp target/<node-ip>/services/kube-scheduler.service <user>@<node-ip>:/etc/systemd/system/ $ scp target/<node-ip>/configs/kube-scheduler.config.yaml <user>@<node-ip>:/etc/kubernetes/
# 启动服务 $ systemctl daemon-reload && systemctl enable kube-scheduler && systemctl restart kube-scheduler # 检查状态 $ service kube-scheduler status # 查看日志 $ journalctl -f -u kube-scheduler # 查看leader $ kubectl get endpoints kube-scheduler --namespace=kube-system -o yaml
# 建立 token $ cd target/pki/admin $ export BOOTSTRAP_TOKEN=$(kubeadm token create \ --description kubelet-bootstrap-token \ --groups system:bootstrappers:worker \ --kubeconfig kube.config) # 设置集群参数 $ kubectl config set-cluster kubernetes \ --certificate-authority=../ca.pem \ --embed-certs=true \ --server=https://<MASTER_VIP>:6443 \ --kubeconfig=kubelet-bootstrap.kubeconfig # 设置客户端认证参数 $ kubectl config set-credentials kubelet-bootstrap \ --token=${BOOTSTRAP_TOKEN} \ --kubeconfig=kubelet-bootstrap.kubeconfig # 设置上下文参数 $ kubectl config set-context kubelet@kubernetes \ --cluster=kubernetes \ --user=kubelet-bootstrap \ --kubeconfig=kubelet-bootstrap.kubeconfig # 设置默认上下文 $ kubectl config use-context kubelet@kubernetes --kubeconfig=kubelet-bootstrap.kubeconfig # 把生成的配置copy到每一个worker节点上 $ scp kubelet-bootstrap.kubeconfig <user>@<node-ip>:/etc/kubernetes/kubelet-bootstrap.kubeconfig # 把ca分发到每一个worker节点 $ scp target/pki/ca.pem <user>@<node-ip>:/etc/kubernetes/pki/ # 查看生成的 token $ kubeadm token list --kubeconfig ~/.kube/config
system:bootstrap:<Token ID>
,group 设置为 system:bootstrappers
,后续将为这个 group 设置 ClusterRoleBinding;把kubelet配置文件分发到每一个worker节点上
$ scp target/worker-<node-ip>/kubelet.config.json <user>@<node-ip>:/etc/kubernetes/
cat kubelet.config.json { "kind": "KubeletConfiguration", "apiVersion": "kubelet.config.k8s.io/v1beta1", "authentication": { "x509": { "clientCAFile": "/etc/kubernetes/pki/ca.pem" }, "webhook": { "enabled": true, "cacheTTL": "2m0s" }, "anonymous": { "enabled": false } }, "authorization": { "mode": "Webhook", "webhook": { "cacheAuthorizedTTL": "5m0s", "cacheUnauthorizedTTL": "30s" } }, "address": "172.18.0.103", "staticPodPath": "", "port": 10250, "readOnlyPort": 10255, "cgroupDriver": "cgroupfs", "hairpinMode": "promiscuous-bridge", "serializeImagePulls": false, "featureGates": { "RotateKubeletClientCertificate": true, "RotateKubeletServerCertificate": true }, "clusterDomain": "cluster.local.", "clusterDNS": ["10.96.0.2"] }
同时配置了以下受权参数:
kubelet 收到请求后,使用 clientCAFile 对证书签名进行认证,或者查询 bearer token 是否有效。若是二者都没经过,则拒绝请求,提示 Unauthorized:
把kubelet服务文件分发到每一个worker节点上
$ scp target/worker-<node-ip>/kubelet.service <user>@<node-ip>:/etc/systemd/system/
kublet 启动时查找配置的 --kubeletconfig 文件是否存在,若是不存在则使用 --bootstrap-kubeconfig 向 kube-apiserver 发送证书签名请求 (CSR)。
kube-apiserver 收到 CSR 请求后,对其中的 Token 进行认证(事先使用 kubeadm 建立的 token),认证经过后将请求的 user 设置为 system:bootstrap:,group 设置为 system:bootstrappers,这就是Bootstrap Token Auth。
# bootstrap附权 $ kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers # 启动服务 $ mkdir -p /var/lib/kubelet $ mkdir -p /var/log/kubernetes $ systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet # 在master上Approve bootstrap请求 $ kubectl get csr $ kubectl certificate approve <name> # 查看服务状态 $ service kubelet status # 查看日志 $ journalctl -f -u kubelet
查看证书请求文件。
$ cd target/pki/proxy cat kube-proxy-csr.json { "CN": "system:kube-proxy", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "seven" } ] }
system:kube-proxy
;system:node-proxier
将User system:kube-proxy
与 Role system:node-proxier
绑定,该 Role 授予了调用 kube-apiserver
Proxy 相关 API 的权限;$ cfssl gencert -ca=../ca.pem \ -ca-key=../ca-key.pem \ -config=../ca-config.json \ -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
# 建立kube-proxy.kubeconfig $ kubectl config set-cluster kubernetes \ --certificate-authority=../ca.pem \ --embed-certs=true \ --server=https://<master-vip>:6443 \ --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 kube-proxy@kubernetes \ --cluster=kubernetes \ --user=kube-proxy \ --kubeconfig=kube-proxy.kubeconfig $ kubectl config use-context kube-proxy@kubernetes --kubeconfig=kube-proxy.kubeconfig # 分发kube-proxy.kubeconfig 到 node 节点 $ scp kube-proxy.kubeconfig <user>@<node-ip>:/etc/kubernetes/
$ scp target/worker-<node-ip>/kube-proxy.config.yaml <user>@<node-ip>:/etc/kubernetes/
$ scp target/services/kube-proxy.service <user>@<node-ip>:/etc/systemd/system/
# 建立依赖目录 $ mkdir -p /var/lib/kube-proxy # 启动服务 $ systemctl daemon-reload && systemctl enable kube-proxy && systemctl restart kube-proxy # 查看状态 $ service kube-proxy status # 查看日志 $ journalctl -f -u kube-proxy
目前是 iptables 模式,使用 ipvs 模式能够修改文件 kube-proxy.config.yaml
我这里遇到的一个问题是 iptables 版本太低,若是遇到,能够编译安装使用新版本。
咱们使用calico官方的安装方式来部署。
# 建立目录(在配置了kubectl的节点上执行) $ mkdir -p /etc/kubernetes/addons # 上传calico配置到配置好kubectl的节点(一个节点便可) $ scp target/addons/calico.yaml <user>@<node-ip>:/etc/kubernetes/addons/ # 部署calico $ kubectl apply -f /etc/kubernetes/addons/calico.yaml # 查看状态 $ kubectl get pods -n kube-system
https://docs.projectcalico.org/v3.10/getting-started/kubernetes/
# 上传配置文件 $ scp target/addons/coredns.yaml <user>@<node-ip>:/etc/kubernetes/addons/ # 部署coredns $ kubectl apply -f /etc/kubernetes/addons/coredns.yaml
https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base
# 写入配置 $ cat > nginx-ds.yml <<EOF apiVersion: v1 kind: Service metadata: name: nginx-ds labels: app: nginx-ds spec: type: NodePort selector: app: nginx-ds ports: - name: http port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ds labels: addonmanager.kubernetes.io/mode: Reconcile spec: template: metadata: labels: app: nginx-ds spec: containers: - name: my-nginx image: nginx:1.7.9 ports: - containerPort: 80 selector: matchLabels: app: nginx-ds EOF # 建立ds $ kubectl apply -f nginx-ds.yml
# 检查各 Node 上的 Pod IP 连通性(主节点没有calico因此不能访问podip) $ kubectl get pods -o wide # 在每一个worker节点上ping pod ip $ ping <pod-ip> # 检查service可达性 $ kubectl get svc # 在每一个worker节点上访问服务(主节点没有proxy因此不能访问service-ip) $ curl <service-ip>:<port> # 在每一个节点检查node-port可用性 $ curl <node-ip>:<port>
# 建立一个nginx pod $ cat > pod-nginx.yaml <<EOF apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 EOF # 建立pod $ kubectl apply -f pod-nginx.yaml # 进入pod,查看dns $ kubectl exec nginx -it -- /bin/bash # 查看dns配置 root@nginx:/# cat /etc/resolv.conf # 查看名字是否能够正确解析 root@nginx:/# ping nginx-ds root@nginx:/# ping kubernetes
# 上传dashboard配置 $ scp target/addons/dashboard-all.yaml <user>@<node-ip>:/etc/kubernetes/addons/ # 建立服务 $ kubectl apply -f /etc/kubernetes/addons/dashboard-all.yaml # 查看服务运行状况 $ kubectl get deployment kubernetes-dashboard -n kube-system $ kubectl --namespace kube-system get pods -o wide $ kubectl get services kubernetes-dashboard -n kube-system $ netstat -ntlp|grep 8401
为了集群安全,从 1.7 开始,dashboard 只容许经过 https访问,咱们使用nodeport的方式暴露服务,可使用 https://NodeIP:NodePort 地址访问。
关于自定义证书
默认dashboard的证书是自动生成的,确定是非安全的证书,若是你们有域名和对应的安全证书能够本身替换掉。使用安全的域名方式访问dashboard。
在dashboard-all.yaml中增长dashboard启动参数,能够指定证书文件,其中证书文件是经过secret注进来的。
--tls-cert-file=dashboard.cer --tls-key-file=dashboard.key
Dashboard 默认只支持 token 认证,因此若是使用 KubeConfig 文件,须要在该文件中指定 token,咱们这里使用token的方式登陆
# 建立service account $ kubectl create sa dashboard-admin -n kube-system # 建立角色绑定关系 $ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin # 查看dashboard-admin的secret名字 $ ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}') # 打印secret的token $ kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}'
metrics-server 经过 kube-apiserver 发现全部节点,而后调用 kubelet APIs(经过 https 接口)得到各节点(Node)和 Pod 的 CPU、Memory 等资源使用状况。
从 Kubernetes 1.12 开始,kubernetes 的安装脚本移除了 Heapster,从 1.13 开始彻底移除了对 Heapster 的支持,Heapster 再也不被维护。
$ cd target/addons $ git clone https://github.com/kubernetes-incubator/metrics-server.git $ cd metrics-server/deploy/1.8+/
修改metrics-server-deployment.yaml
文件,把 metrics-server 修改成以下命令行参数:
containers: - name: metrics-server image: wangzan18/metrics-server-amd64:v0.3.6 args: - --cert-dir=/tmp - --secure-port=4443 - --metric-resolution=30s - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
$ cd target/addons/metrics-server/deploy/1.8+/ $ kubectl apply -f .