Kubeadm 安裝部署 Kubernetes 集群


閱讀目錄:

  1. 准備工作
  2. 部署 Master 管理節點
  3. 部署 Minion 工作節點
  4. 部署 Hello World 應用
  5. 安裝 Dashboard 插件
  6. 安裝 Heapster 插件
  7. 后記

相關文章: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,將hostnamehost修改如下:

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:8080API 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: NodePortclusterIP並不需要更改,然后保存下。

查看分配的 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-n4sjckubernetes-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

解決方案(Failed to list *v1.Namespace: User "system:serviceaccount:kube-system:heapster" cannot list namespaces 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,其實我個人覺得是微服務編排領域最強的那個,提供一系列強大的功能,但因為涉及的東西非常多,並且都需要花多的時間去研究消化,所以,這篇文章只是投石問路,后面需要學習的還有很多。

參考資料:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM