項目致力於讓有意向使用原生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 .