1. 程式人生 > >升級到Kubernetes1.8.4的配置細節差異以及k8s幾個不常見的坑

升級到Kubernetes1.8.4的配置細節差異以及k8s幾個不常見的坑

kubernetes已經發布了1.8,今天需要在一個新機房部署k8s環境,於是決定嘗試最新版本1.8,部署過程中故意和以前的部署步驟有些不同,故而出現了一些問題,並且發現k8s這有個新版本本身幾個差異地方記錄如下:

1.首先遇到的問題便是get-kub-binaries.sh執行之後,無法正常下載到新版的程式壓縮包了,在1.7以前都不需要科學上網就可以下載的。我只好在設定好代理的伺服器上執行它下載好,然後傳到伺服器上把client按照以前舊版本的路徑規劃解壓到platform目錄下,把server直接解壓到server目錄。

2.kubelet的啟動引數中,--require-kubeconfig

已經不用了,如果配置了會在日誌中看到警告。並且,--experimental-bootstrap-kubeconfig已經去掉了experimental-這個單詞

3.新版本的kubelet啟動時會嚴格判斷swap是否開啟,如果開啟會報錯,使用sfdisk -l檢視一下哪個區分是swap分割槽,使用swapoff /dev/xvda2這樣的命令把它關閉,或者直接swapoff -a關閉所有的swap分割槽,並且把/etc/fstab檔案中指定swap那一行刪除,使用swapoff 命令報錯提示無法分配到記憶體。那是因為記憶體已經使用了太多,超過了實體記憶體,使用了swap,所以必需釋放一些記憶體以便作業系統將swap中已經使用的轉移到實體記憶體中,如果是docker啟動了太多容器,systemctl restart docker就可以了。另外一種方式是在配置檔案中指定

--fail-swap-on為false,但是這樣會影響k8s的排程決策演算法。

4.在1.8.4增加了Node Authorization機制,需要在apiserver中的配置檔案中--authorization-mode=增加一個Node值,並在--admission-control=...,增加一個NodeRestriction,..不然會報錯。並刪除system:node cluster role binding

5.dashboard從1.7.1升級到1.8.0時,移除了kubernetes-dashboard-init-amd64這個映象,僅使用kubernetes-dashboard-amd64映象就可以了,但是配置tls的金鑰的路徑卻由絕對路徑改為了相對路徑,原來的- --tls-key-file=/certs/tls.key和 - --tls-cert-file=/certs/tls.crt要改為- --tls-key-file=tls.key和          - --tls-cert-file=tls.crt,否則會報一個錯誤open /certs//certs/tls.crt: no such file or directory,然後就失敗了。

順便記錄一下我遇到的幾個不常見的坑。

1.網路上的示例都是使用自簽名的證書,我嘗試了採用CA簽名的證書,因為是萬用字元2級域名的,所以嘗試了好多次都失敗了,甚至ETCD叢集本身使用這種CA機構簽名的證書都不能建立起叢集。由於對證收的檢驗機制還算不上完全掌握,所以暫時放棄。

2.如果在啟動kubelet時,日誌中提示No api server defined - no node status update will be sent.這很有可能是kubelet的配置檔案或啟動引數中忘記指定api-server或者引數寫錯了。

3.如果一個node已經發送了certificate請求,並且在master上已經approve了,但是檢視csr的狀態卻發現只有approved,沒有issued,這很可能是kube-manager-controller沒有啟動或者是無意停掉了。我因為這個事情就浪費了一上午的時間去排查,最後才發現這個原因。

4.在pod中使用nfs時,如果提示一個錯誤

09/volumes/kubernetes.io~nfs/nfs-data-storage
Output: Running scope as unit run-30478.scope.
mount: wrong fs type, bad option, bad superblock on 10.0.0.150:/data,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)


       In some cases useful info is found in syslog - try
       dmesg | tail or so.

那是因為pod所在的node沒有安裝nfs-utils,最好在每個node上都安裝好nfs-utils

5.如果啟動kubelet時報錯failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User "kubelet-bootstrap" cannot create certificatesigningrequests,是由於在master上忘記建立

clusterrolebinding ,執行kubectl create--insecure-skip-tls-verifyclusterrolebinding kubelet-bootstrap \ --clusterrole=system:node-bootstrapper \ --user=kubelet-bootstrap就可以解決了。6.nginx-ingress的https問題,已經配置好了證書,後端是k8s的dashboard元件,它也是必需用https訪問,但在官網的示例中大都在nginx就終止了tls,轉向後端http了。這樣訪問時會在dashboard中輸出錯誤http: TLS handshake error from 10.1.64.0:51000: tls: first record does not look like a TLS handshake,而看nginx-ingress-controller也會有一個錯誤,大致表現為:[error] 3790#3790: *215 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: x.x.x.x, server: k8s.domain.com, request: "GET / HTTP/2.0", upstream: "http://10.1.x.x:8443/", host: "k8s.domain.com",進一步檢視對應的ingress生成的nginx配置檔案,發現它轉發的上游是http並非https,所以導致這個錯誤,檢視官方文件得知,需要在metadata指定一下metadata,annotations: ingress.kubernetes.io/ssl-passthrough: "true"

7.nginx-ingress代理k8s的dashboard的問題,如果我們有許可權機構發放的證書,肯定希望訪問k8s的dashboard時也使用這個證書,瀏覽器的位址列是綠色的多酷啊。但是k8s的dashboard的官方示例中,證書是叫做dashboard.crt和dashboard.key,它的yaml檔案中也是指定這兩個檔名。如果ingress也使用通過這兩個檔案建立的那個secret,dashboard啟動沒有問題,ingress-controller會報錯,error obtaining PEM from secret kube-system/kubernetes-dashboard-certs: no keypair or CA cert could be found in kube-system/kubernetes-dashboard-certs,其實並不是真的證書有問題,而是它預設尋找的是叫tls.crt和tls.key的證書,所以這個dashboard.crt它不能正確的識別。

8.當啟用了nginx-ingress-controller的basic認證時,日誌中出現錯誤 [crit] 1438#1438: *11994 crypt_r() failed (22: Invalid argument)。原來是由於在建立密碼檔案時使用了htpasswd命令中的-B選項(

-B Force bcrypt encryption of the password (very secure).),在docker-registry倉庫的認證是支援這種方式的,但在nginx中是不支援的,所以不能使用-B選項

9. traefik-ingress-controller它不支援ingress.kubernetes.io/ssl-passthrough這個annotation,寫了也不起作用的。

10.部署一個deploy卻發現一直是pending狀態,檢查pod描述顯示nodes are available: xx PodToleratesNodeTaints.這是因為沒有合適的node排程,為什麼不能排程呢,檢視node的描述發現Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule。這裡表示指定了cloudprvider但是卻沒有初始化。解決的辦法要麼初始化cloudprovider(在國內只嘗試過阿里雲https://github.com/AliyunContainerService/alicloud-controller-manager),要麼就把-cloud-provider=external這些去掉,但是去掉之後那些node的Taints並不會消失,需要手動刪除掉kubectl patch node 10.x.x.x -p '{"spec":{"taints":[]}}'

持續更新....