閱讀目錄:
- 准備工作
- 部署 Master 管理節點
- 部署 Minion 工作節點
- 部署 Hello World 應用
- 安裝 Dashboard 插件
- 安裝 Heapster 插件
- 后記
相關文章:Kubernetes 概念整理
關於 Kubernetes 的相關概念內容,上面這篇文章已經整理的很詳細了,這邊就不再進行敘述了。
這篇文章主要記錄的是 Kubernetes 的安裝部署過程,我們都知道 Kubernetes 是由眾多的組件組成的(而且很多都是在 Google 源下,你懂的),本來我是想全手動安裝的,但后來 Google 找了很多的資料,也嘗試了很長時間,發現工程量太大,而且也太復雜,所以只能暫時放棄了。
不過,后來無意間找到了一篇很好的部署教程,以后再嘗試下。
退而求其次,不能全手動安裝,那就使用 Kubeadm 安裝工具進行部署,但 Kubeadm 目前還不能用於生產環境,所以,我們只能在測試環境進行安裝部署。
廢話不多說,我們開干(歷時一個多月左右😂)。
1. 准備工作
先說下我安裝部署的環境:
- 主機環境:Mac OS High Sierra
- 虛擬機環境:Ubuntu 16.04
- 虛擬機工具:Vagrant
因為我電腦空間有限,所以暫時只能部署兩個虛擬機,一個是 Master 管理節點,一個是 Minion 工作節點,如下:
manager1 10.9.10.154
worker1 10.9.10.152
兩個虛擬機的創建使用的 Vagrant 工具(參考文章:Mac OS 使用 Vagrant 管理虛擬機),為了使用橋接網絡模式(獨立的 IP 地址訪問),別忘了在Vagrantfile
中,增加下面配置:
config.vm.network "public_network", bridge: "en0: Wi-Fi (AirPort)"
config.vm.boot_timeout = 2000
兩個虛擬機創建好之后,使用下面命令,分別創建root
賬號:
$ vagrant ssh
$ sudo passwd root
$ su root
然后分別編輯/etc/hostname
和/etc/hosts
,將hostname
和host
修改如下:
manager1
10.9.10.154 manager1
worker1
10.9.10.152 worker1
因為安裝部署過程需要訪問 Google 源,所以我們還需要配置代理(連接的是 Mac 主機的代理服務器,我使用的是 Shadowsocks,需要在“偏好設置”中配置“HTTP 代理”):
export http_proxy=http://10.9.10.215:1087;export https_proxy=http://10.9.10.215:1087;
設置好之后,我們可以檢查下是否生效:
$ curl ip.cn
當前 IP:185.225.14.5 來自:美國
然后,我們再分別配置 Docker 環境,參考文檔:Get Docker CE for Ubuntu
$ apt-get update && apt-get install docker.io
$ docker version
Client:
Version: 1.13.1
API version: 1.26
Go version: go1.6.2
Git commit: 092cba3
Built: Thu Nov 2 20:40:23 2017
OS/Arch: linux/amd64
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Go version: go1.6.2
Git commit: 092cba3
Built: Thu Nov 2 20:40:23 2017
OS/Arch: linux/amd64
Experimental: false
然后,再配置 Docker 代理(拉取 Google 鏡像),參考文章:centos7 docker 使用 https_proxy 代理配置
創建目錄和文件http-proxy.conf
,並在文件中添加后面的代理配置:
$ mkdir /etc/systemd/system/docker.service.d
$ touch /etc/systemd/system/docker.service.d/http-proxy.conf
$ vi /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://10.9.10.215:1087" "HTTPS_PROXY=https://10.9.10.215:1087"
然后重啟 Docker 服務,檢查代理是否生效:
$ systemctl daemon-reload
$ systemctl restart docker
$ systemctl show docker --property Environment
Environment=HTTP_PROXY=http://10.9.10.215:1087 HTTPS_PROXY=https://10.9.10.215:1087
至此,管理節點和工作節點的准備工作都做好了。
Master 管理節點包含組件:
docker
etcd
kube-apiserver
kube-controller-manager
kubelet
kube-scheduler
Minion 工作節點包含組件:
docker
kubelet
kube-proxy
2. 部署 Master 管理節點
Kubeadm 安裝 Kubernetes 命令:
$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl
Kubeadm 初始化集群:
$ kubeadm init --pod-network-cidr=10.244.0.0/16
unable to get URL "https://dl.k8s.io/release/stable-1.9.txt": Get https://storage.googleapis.com/kubernetes-release/release/stable-1.9.txt: dial tcp 216.58.200.48:443: i/o timeout
但是出現了上面的錯誤,解決方案(需要指定版本):
重新執行命令(指定版本為1.9.0
):
$ kubeadm init --kubernetes-version=1.9.0 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.9.10.154 --node-name=manager1
[init] Using Kubernetes version: v1.9.0
[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks.
[WARNING FileExisting-crictl]: crictl not found in system path
[preflight] Starting the kubelet service
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [manager1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.9.10.154]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "scheduler.conf"
[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
[init] This might take a minute or longer if the control plane images have to be pulled.
[apiclient] All control plane components are healthy after 29.006486 seconds
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[markmaster] Will mark node manager1 as master by adding a label and a taint
[markmaster] Master manager1 tainted and labelled with key/value: node-role.kubernetes.io/master=""
[bootstraptoken] Using token: 561fd3.febddbbda0c219bc
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: kube-dns
[addons] Applied essential addon: kube-proxy
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join --token 1b43ed.7391162ed9072892 10.9.10.154:6443 --discovery-token-ca-cert-hash sha256:6ab593dfe4d2822912d11cf009830dd033591a6285e4b5ce4505c39d4b40f12b
因為初始化集群的時候,我們指定了參數--pod-network-cidr=10.244.0.0/16
,表示我們選擇的網絡組件是 Flannel,所以,我們還需要安裝 Flannel,命令:
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
The connection to the server localhost:8080 was refused - did you specify the right host or port?
出現了上面的錯誤,解決方案:1.6.1 The connection to the server localhost:8080 was refused
$ sudo cp /etc/kubernetes/admin.conf $HOME/
$ sudo chown $(id -u):$(id -g) $HOME/admin.conf
$ export KUBECONFIG=$HOME/admin.conf
其實上面的解決方式,在初始化集群的打印信息里面就有,要求我們設置環境變量KUBECONFIG
為配置文件的路徑,以便后續的使用。
重新執行安裝 Flannel 命令:
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
clusterrole "flannel" created
clusterrolebinding "flannel" created
serviceaccount "flannel" created
configmap "kube-flannel-cfg" created
daemonset "kube-flannel-ds" created
然后,執行查看節點命令:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
manager1 NotReady master 47m v1.9.2
節點狀態為 NotReady,需要執行下面命令解決:
$ kubectl taint nodes --all node-role.kubernetes.io/master-
node "manager1" untainted
重新執行查看節點命令(變為了 Ready):
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
manager1 Ready master 48m v1.9.2
至此,我們在 Master 管理節點,使用 Kubeadm 成功安裝部署了 Kubernetes。
查看集群信息命令:
$ kubectl cluster-info
Kubernetes master is running at https://10.9.10.154:6443
KubeDNS is running at https://10.9.10.154:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
查看所有的 Pod 命令:
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-manager1 1/1 Running 0 23h
kube-system kube-apiserver-manager1 1/1 Running 0 23h
kube-system kube-controller-manager-manager1 1/1 Running 0 23h
kube-system kube-dns-6f4fd4bdf-8sbrt 3/3 Running 0 23h
kube-system kube-flannel-ds-j625p 1/1 Running 0 23h
kube-system kube-proxy-jn9hl 1/1 Running 0 23h
kube-system kube-scheduler-manager1 1/1 Running 0 23h
kube-system kubernetes-dashboard-845747bdd4-6fsc4 1/1 Running 0 23h
如果我們安裝部署中間出現了什么問題,可以使用kubeadm reset
還原命令,重新進行安裝部署 Kubernetes。
3. 部署 Minion 工作節點
Kubeadm 安裝 Kubernetes 命令:
$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl
安裝成功之后,將工作節點加入到集群中,執行下面命令:
$ kubeadm join --token 1b43ed.7391162ed9072892 10.9.10.154:6443 --discovery-token-ca-cert-hash sha256:6ab593dfe4d2822912d11cf009830dd033591a6285e4b5ce4505c39d4b40f12b
[preflight] Running pre-flight checks.
[WARNING FileExisting-crictl]: crictl not found in system path
[discovery] Trying to connect to API Server "10.9.10.154:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.9.10.154:6443"
[discovery] Requesting info from "https://10.9.10.154:6443" again to validate TLS against the pinned public key
[discovery] Failed to request cluster info, will try again: [Get https://10.9.10.154:6443/api/v1/namespaces/kube-public/configmaps/cluster-info: x509: certificate has expired or is not yet valid]
[discovery] Failed to request cluster info, will try again: [Get https://10.9.10.154:6443/api/v1/namespaces/kube-public/configmaps/cluster-info: x509: certificate has expired or is not yet valid]
出現了上面錯誤,原因是工作節點和管理節點的時間沒同步(執行命令date
檢查),解決方案:kubeadm join Endpoint check failed
具體就是安裝ntp
服務,使兩台服務器的時間進行同步。
重新執行命令:
$ kubeadm join --token 1b43ed.7391162ed9072892 10.9.10.154:6443 --discovery-token-ca-cert-hash sha256:6ab593dfe4d2822912d11cf009830dd033591a6285e4b5ce4505c39d4b40f12b
[preflight] Running pre-flight checks.
[WARNING FileExisting-crictl]: crictl not found in system path
[discovery] Trying to connect to API Server "10.9.10.154:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.9.10.154:6443"
[discovery] Requesting info from "https://10.9.10.154:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "10.9.10.154:6443"
[discovery] Successfully established connection with API Server "10.9.10.154:6443"
This node has joined the cluster:
* Certificate signing request was sent to master and a response
was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
可以看到,工作節點加入集群成功了,然后,我們可以在工作節點上,執行查看節點命令:
$ kubectl get nodes
The connection to the server localhost:8080 was refused - did you specify the right host or port?
出現了上面的錯誤,這個錯誤和我們在管理節點配置集群的時候,是一樣的,什么原因呢?就是 kubectl 默認連接的是localhost:8080
API Server,所以,需要我們手動配置環境變量。
查看/etc/kubernetes/kubelet.conf
配置信息:
$ cat /etc/kubernetes/kubelet.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: .......
server: https://10.9.10.154:6443
name: default-cluster
contexts:
- context:
cluster: default-cluster
namespace: default
user: default-auth
name: default-context
current-context: default-context
kind: Config
preferences: {}
users:
- name: default-auth
user:
client-certificate: /var/lib/kubelet/pki/kubelet-client.crt
client-key: /var/lib/kubelet/pki/kubelet-client.key
可以看到,上面有我們管理節點的 API Server 地址(https://10.9.10.154:6443),然后我們將此配置文件,配置為環境變量:
$ sudo cp /etc/kubernetes/kubelet.conf $HOME/
$ sudo chown $(id -u):$(id -g) $HOME/kubelet.conf
$ export KUBECONFIG=$HOME/kubelet.conf
然后在工作節點上,重新執行查看節點命令:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
manager1 Ready master 18h v1.9.2
worker1 Ready <none> 57m v1.9.3
這樣,我們就可以在工作節點上,使用kubectl
命令查看集群信息了(只能查看,不能操作),但其實還是通過訪問 API Server,來獲取集群信息。
至此,我們工作節點的部署就完成了。
4. 部署 Hello World 應用
Kubernetes 節點配置好之后,下面我們就部署一個示例應用,部署參考:Use a Service to Access an Application in a Cluster
創建一個名稱為hello-workd
的 Deployment:
$ kubectl run hello-world --replicas=1 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
deployment "hello-world" created
--replicas=1
表示我們創建的 Pod 數量為 1,--port=8080
是容器的端口,並不是外部訪問的端口。
創建好之后,我們可以通過下面幾個命令,查看部署的信息和進度:
$ kubectl get deployments hello-world
$ kubectl describe deployments hello-world
$ kubectl get replicasets
$ kubectl describe replicasets
部署成功之后,我們還需要創建對應的 Service(類型為 NodePort):
$ kubectl expose deployment hello-world --type=NodePort --name=example-service
service "example-service" exposed
創建好之后,我們查看下 Service 的信息(31860 就是對外暴露的端口):
$ kubectl describe services example-service
Name: example-service
Namespace: default
Labels: run=load-balancer-example
Annotations: <none>
Selector: run=load-balancer-example
Type: NodePort
IP: 10.96.52.166
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 31860/TCP
Endpoints: 10.244.3.8:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
我們還可以查看 Pod 的信息:
$ kubectl get pods --selector="run=load-balancer-example" --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
hello-world-58f9949f8-c28gx 1/1 Running 0 15m 10.244.3.8 worker1
然后,我們就可以瀏覽器直接打開(http://10.9.10.152:31860/),10.9.10.152
是 worker1 的 IP 地址,或者直接測試訪問命令:
$ curl http://10.9.10.152:31860/
Hello Kubernetes!
另外,說明下 Kubernetes 三種暴露服務的方式:
- LoadBlancer Service:LoadBlancer Service 是 kubernetes 深度結合雲平台的一個組件;當使用 LoadBlancer Service 暴露服務時,實際上是通過向底層雲平台申請創建一個負載均衡器來向外暴露服務;目前 LoadBlancer Service 支持的雲平台已經相對完善,比如國外的 GCE、DigitalOcean,國內的 阿里雲,私有雲 Openstack 等等,由於 LoadBlancer Service 深度結合了雲平台,所以只能在一些雲平台上來使用。
- NodePort Service:NodePort Service 顧名思義,實質上就是通過在集群的每個 node 上暴露一個端口,然后將這個端口映射到某個具體的 service 來實現的,雖然每個 node 的端口有很多(0~65535),但是由於安全性和易用性(服務多了就亂了,還有端口沖突問題)實際使用可能並不多。
- Ingress:Ingress 這個東西是 1.2 后才出現的,通過 Ingress 用戶可以實現使用 nginx 等開源的反向代理負載均衡器實現對外暴露服務。
5. 安裝 Dashboard 插件
Kubernetes Dashboard 地址:https://github.com/kubernetes/dashboard
Kubectl 安裝 Dashboard 命令:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role "kubernetes-dashboard-minimal" created
rolebinding "kubernetes-dashboard-minimal" created
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
刪除安裝的 Dashboard 配置命令:
$ kubectl -n kube-system delete $(kubectl -n kube-system get pod -o name | grep dashboard)
pod "kubernetes-dashboard-3313488171-7706x" deleted
上面安裝的 Dashboard 只能本機訪問,如果需要外網訪問,需要再進行配置一下,參考資料:Accessing Dashboard 1.7.X and above
需要先刪除下 Dashboard,然后再執行kubectl apply -f ...
創建命令,然后執行下面的命令(2. 修改 kubernetes-dashboard Service):
$ kubectl -n kube-system edit service kubernetes-dashboard
會出現如下配置信息:
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},"name":"kubernetes-dashboard","namespace":"kube-system"},"spec":{"ports":[{"port":443,"targetPort":8443}],"selector":{"k8s-app":"kubernetes-dashboard"}}}
creationTimestamp: 2018-02-08T05:30:23Z
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
resourceVersion: "6652"
selfLink: /api/v1/namespaces/kube-system/services/kubernetes-dashboard
uid: 29323549-0c91-11e8-98f6-0293061ca64f
spec:
clusterIP: 10.97.21.104
externalTrafficPolicy: Cluster
ports:
- nodePort: 30835
port: 443
protocol: TCP
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
然后將type: ClusterIP
修改為type: NodePort
,clusterIP
並不需要更改,然后保存下。
查看分配的 NodePort(NodePort 30835 映射到 Dashboard pod 433 端口):
$ kubectl get services kubernetes-dashboard -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort 10.97.21.104 <none> 443:30835/TCP 29m
然后,檢查 Controller 是否正常運行:
$ kubectl get deployment kubernetes-dashboard -n kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kubernetes-dashboard 1 1 1 1 30m
$ kubectl get pods -n kube-system | grep dashboard
kubernetes-dashboard-845747bdd4-r4xsj 1/1 Running 0 30m
訪問 Dashboard 的三種方式(參考資料:安裝 Dashboard 插件):
- kubernetes-dashboard 服務暴露了 NodePort,可以使用 http://NodeIP:nodePort 地址訪問 Dashboard。
- 通過 API Server 訪問 Dashboard(https 6443 端口和 http 8080 端口方式)。
- 通過 kubectl proxy 訪問 Dashboard。
5.1 NodePort 方式訪問
上面的配置,其實就是第一種,我們直接就可以訪問:https://10.9.10.154:30835/
5.2 kubectl proxy 方式訪問
第二種方式,需要配置證書,網上有相關資料,這邊就不敘述了,第三種方式,執行命令:
$ kubectl proxy --address='10.9.10.154' --port=8086 --accept-hosts='^*$'
Starting to serve on 10.9.10.154:8086
需要指定--accept-hosts
選項,否則瀏覽器訪問 Dashboard 頁面時提示“Unauthorized”
,瀏覽器訪問 URL:http://10.9.10.154:8086/ui 自動跳轉到:http://10.9.10.154:8086/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/#/workload?namespace=default
打開 https://10.9.10.154:30835/#!/login,然后會出現下面的登錄窗口(也可以選擇“跳過”,只不過沒有權限操作):
5.3 token 方式登錄
這里我們選擇 token 方式登錄,參考資料:Access control
執行命令:
$ kubectl -n kube-system get secret
NAME TYPE DATA AGE
attachdetach-controller-token-tlj4p kubernetes.io/service-account-token 3 2h
bootstrap-signer-token-vdkth kubernetes.io/service-account-token 3 2h
bootstrap-token-561fd3 bootstrap.kubernetes.io/token 7 2h
certificate-controller-token-w9bb7 kubernetes.io/service-account-token 3 2h
clusterrole-aggregation-controller-token-bztd8 kubernetes.io/service-account-token 3 2h
cronjob-controller-token-4f7t4 kubernetes.io/service-account-token 3 2h
daemon-set-controller-token-q7865 kubernetes.io/service-account-token 3 2h
default-token-khxp8 kubernetes.io/service-account-token 3 2h
deployment-controller-token-vlsrk kubernetes.io/service-account-token 3 2h
disruption-controller-token-mfnwh kubernetes.io/service-account-token 3 2h
endpoint-controller-token-hm69z kubernetes.io/service-account-token 3 2h
flannel-token-mrzqq kubernetes.io/service-account-token 3 52m
generic-garbage-collector-token-m78z6 kubernetes.io/service-account-token 3 2h
horizontal-pod-autoscaler-token-c6v4w kubernetes.io/service-account-token 3 2h
job-controller-token-jkf4b kubernetes.io/service-account-token 3 2h
kube-dns-token-qvqhk kubernetes.io/service-account-token 3 2h
kube-proxy-token-rqjdn kubernetes.io/service-account-token 3 2h
kubernetes-dashboard-certs Opaque 0 47m
kubernetes-dashboard-key-holder Opaque 2 47m
kubernetes-dashboard-token-n4sjc kubernetes.io/service-account-token 3 47m
namespace-controller-token-qvblb kubernetes.io/service-account-token 3 2h
node-controller-token-qpz8t kubernetes.io/service-account-token 3 2h
persistent-volume-binder-token-qfrkh kubernetes.io/service-account-token 3 2h
pod-garbage-collector-token-trzhf kubernetes.io/service-account-token 3 2h
replicaset-controller-token-gp75m kubernetes.io/service-account-token 3 2h
replication-controller-token-9tmhr kubernetes.io/service-account-token 3 2h
resourcequota-controller-token-2djtx kubernetes.io/service-account-token 3 2h
service-account-controller-token-vxkp8 kubernetes.io/service-account-token 3 2h
service-controller-token-q54bc kubernetes.io/service-account-token 3 2h
statefulset-controller-token-ldcz9 kubernetes.io/service-account-token 3 2h
token-cleaner-token-lk9kt kubernetes.io/service-account-token 3 2h
ttl-controller-token-9mks8 kubernetes.io/service-account-token 3 2h
找到並復制 Name 為kubernetes-dashboard-token-n4sjc
,然后執行下面命令:
$ kubectl -n kube-system describe secret kubernetes-dashboard-token-n4sjc
Name: kubernetes-dashboard-token-nstpj
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name=kubernetes-dashboard
kubernetes.io/service-account.uid=94dc6cdc-0cb4-11e8-ae1c-0293061ca64f
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi1uc3RwaiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6Ijk0ZGM2Y2RjLTBjYjQtMTFlOC1hZTFjLTAyOTMwNjFjYTY0ZiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.gfYyS4l4z-qjz7_38E9bJ2hg8P173qKPJFVoFxX3uMX4gDgiYQJoCjx6ldiIX8oSVXfg572iUH2qMdCEskYYKbYfYOiuyqLL_O7I6pWic0XbW4qB_h-6PJmlqQUPhwVykDxb3qObnUm97tswbCjic461XqrrL3RwKqL8ox0wyLVhlB-QU4HrHzxUNCinffGLUMznFK0lFp4MfrFCK9TfAZEsXAWycsMBm9g-6ltUUVn7Y7aJrb4jxX5QfCsuKsySYvzOibkdzNGeMM8hVjxofrhE36nbgvpu98zVEcqgtz8ipbBi8K__O0_mlbpb5wCbW8VJuRCegMTKAB19Rb3NLg
然后,我們拿最下面的 token,就可以進行登錄了。
5.4 解決訪問權限問題
不過進去之后,出現了下面的錯誤(token 取的 key 為replicaset-controller-token-kzpmc
,應該是上面的kubernetes-dashboard-token-n4sjc
):
由於 kube-apiserver 啟用了 RBAC 授權,而官方源碼目錄的dashboard-controller.yaml
沒有定義授權的 ServiceAccount,所以后續訪問 API server 的 API 時會被拒絕,Web 中提示:
Forbidden (403)
User "system:serviceaccount:kube-system:default" cannot list jobs.batch in the namespace "default". (get jobs.batch)
解決方案(Update docs to cover RBAC changes in K8S 1.6):
# Create the clusterrole and clusterrolebinding:
# $ kubectl create -f kube-dashboard-rbac.yml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
這個問題搞了我好久,雖然執行了上面的命令,但我試過還是不行的,后來我又重新部署了 Kubernetes 和 Kubernetes Dashboard,然后修改了官方的dashboard-controller.yaml
,在最后增加了上面的配置(我現在用的完整配置:https://github.com/yuezhongxin/Kubernetes.Sample/blob/master/kubernetes-dashboard.yaml)。
安裝命令(1. 不要使用上面命令,直接使用此命令安裝):
$ kubectl apply -f https://github.com/yuezhongxin/Kubernetes.Sample/blob/master/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role "kubernetes-dashboard-minimal" created
rolebinding "kubernetes-dashboard-minimal" created
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created
但當時試過還是不行的,然后隔天我重新啟動虛擬機和 Kubernetes 的時候,發現又可以了,成功的界面:
導致上面配置出錯的原因,我覺得一個是dashboard-controller.yaml
的配置問題,還有一個是 token 取的值不對,之前 token 取的 key 為replicaset-controller-token-kzpmc
,應該是上面的kubernetes-dashboard-token-n4sjc
,kubernetes-dashboard
是上面配置的name
值,這兩個要一一對應,要不然就會出現權限錯誤。
所以,我覺得解決 Dashboard 權限問題的方式:
- 按照完善后的
dashboard-controller.yaml
配置進行創建,而不是使用官方的配置文件。 - 3. 獲取正確的 token 值(key 為
kubernetes-dashboard-token-n4sjc
)。
6. 安裝 Heapster 插件
Heapster 插件包含三部分內容:
- Heapster:顯示各 Nodes、Pods 的 CPU、內存、負載等利用率曲線圖。
- InfluxDB:存儲 Pod 信息相關的數據庫, Heapster 獲取數據之后, 可以指定存儲在 InfluxDB。
- Grafana:這個主要是用於顯示 InfluxDB 里面的數據情況, 可以讓我們很直觀看到數據變化。
到 Heapster release 頁面,下載最新版本的 Heapster。
$ wget https://github.com/kubernetes/heapster/archive/v1.5.1.zip
$ unzip v1.5.1.zip
$ cd heapster-1.5.1/kube-config/influxdb
$ ls
grafana.yaml heapster.yaml influxdb.yaml
部署命令:
$ kubectl create -f .
deployment "monitoring-grafana" created
service "monitoring-grafana" created
serviceaccount "heapster" created
deployment "heapster" created
service "heapster" created
deployment "monitoring-influxdb" created
service "monitoring-influxdb" created
刪除命令:
$ kubectl --namespace kube-system delete deployment heapster &&
kubectl --namespace kube-system delete deployment monitoring-grafana &&
kubectl --namespace kube-system delete deployment monitoring-influxdb &&
kubectl --namespace kube-system delete service heapster &&
kubectl --namespace kube-system delete service monitoring-grafana &&
kubectl --namespace kube-system delete service monitoring-influxdb &&
kubectl --namespace kube-system delete serviceaccounts heapster
查看日志:
$ kubectl get pods -n kube-system
$ kubectl logs -n kube-system -f pods/heapster-5d4dcf5f49-vq64w
E0520 01:18:55.360650 1 reflector.go:190]
k8s.io/heapster/metrics/util/util.go:51: Failed to list *v1.Node: Get
https://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp
10.96.0.1:443: i/o timeout
解決方案:
$ kubectl get services
$ vi heapster.yaml
- --source=kubernetes:https://10.96.0.1
刪除並重新部署,出現下面日志信息:
E0223 08:16:16.766774 1 reflector.go:190] k8s.io/heapster/metrics/util/util.go:30: Failed to list *v1.Node: nodes is forbidden: User "system:serviceaccount:kube-system:heapster" cannot list nodes at the cluster scope
$ kubectl create -f /home/ubuntu/heapster-1.5.1/deploy/kube-config/rbac/heapster-rbac.yaml
clusterrolebinding "heapster" created
刪除並重新部署,出現下面日志信息:
E0223 08:19:45.066213 1 influxdb.go:208] Failed to create influxdb: failed to ping InfluxDB server at "monitoring-influxdb.kube-system.svc:8086" - Get http://monitoring-influxdb.kube-system.svc:8086/ping: dial tcp: lookup monitoring-influxdb.kube-system.svc on 10.96.0.10:53: read udp 10.244.3.25:46031->10.96.0.10:53: i/o timeout
暫時未解決。
感覺是網絡的問題,因為創建的 Servcie 並沒有起作用。
7. 后記
關於 Kubernetes,其實我個人覺得是微服務編排領域最強的那個,提供一系列強大的功能,但因為涉及的東西非常多,並且都需要花多的時間去研究消化,所以,這篇文章只是投石問路,后面需要學習的還有很多。
參考資料: