第2章 Kubernetes安裝配置指南
2.1 系統要求
2.2 使用kubeadm工具快速安裝Kubernetes集群
2.2.1 安裝kubeadm和相關工具
2.2.2 kubeadm config
2.2.3 下載Kubernetes的相關鏡像
2.2.4 運行kubeadm init命令安裝Master
2.2.5 安裝Node,加入集群
2.2.6 安裝網絡插件
2.2.7 驗證Kubernetes集群是否安裝完成
2.3 以二進制文件方式安裝Kubernetes集群
2.3.1 Master上的etcd、kube-apiserver、kube-controller-manager、kube-scheduler服務
2.3.2 Node上的kubelet、kube-proxy服務
2.4 Kubernetes集群的安全設置
2.4.1 基於CA簽名的雙向數字證書認證方式
2.4.2 基於HTTP Base或Token的簡單認證方式
2.5 Kubernetes集群的網絡配置
2.6 內網中的Kubernetes相關配置
2.6.1 Docker Private Registry(私有Docker鏡像庫)
2.6.2 kubelet配置
2.7 Kubernetes的版本升級
2.7.1 二進制升級
2.7.2 使用kubeadm進行集群升級
2.8 Kubernetes核心服務配置詳解
2.8.1 公共配置參數
2.8.2 kube-apiserver啟動參數
2.8.3 kube-controller-manager啟動參數
2.8.4 kube-scheduler啟動參數
2.8.5 kubelet啟動參數
2.8.6 kube-proxy啟動參數
2.9 CRI(容器運行時接口)詳解
2.9.1 CRI概述
2.9.2 CRI的主要組件
2.9.3 Pod和容器的生命周期管理
2.9.4 面向容器級別的設計思路
2.9.5 嘗試使用新的Docker-CRI來創建容器
2.9.6 CRI的進展
2.10 kubectl命令行工具用法詳解
2.10.1 kubectl用法概述
2.10.2 kubectl子命令詳解
2.10.3 kubectl參數列表
2.10.4 kubectl輸出格式
2.10.5 kubectl操作示例
2.1 系統要求
Kubernetes系統由一組可執行程序組成,用戶可以通過GitHub上的Kubernetes項目頁下載編譯好的二進制包,或者下載源代碼並編譯后進行安裝。
安裝Kubernetes對軟件和硬件的系統要求如表2.1所示。
Kubernetes需要容器運行時(Container Runtime Interface,CRI)的支持,目前官方支持的容器運行時包括:Docker、Containerd、CRI-O和frakti。
容器運行時CRI的原理詳見3.9節的說明。本節以Docker作為容器運行環境,推薦版本為Docker CE 18.09。
宿主機操作系統以CentOS Linux 7為例,使用Systemd系統完成對Kubernetes服務的配置。其他Linux發行版的服務配置請參考相關的系統管理手冊。
為了便於管理,常見的做法是將Kubernetes服務程序配置為Linux系統開機自啟動的服務。
需要注意的是,CentOS Linux 7默認啟動了防火牆服務(firewalld),
而Kubernetes的Master與工作Node之間會有大量的網絡通信,安全的做法是在防火牆上配置各組件需要相互通信的端口號,
具體要配置的端口號詳見2.8節各服務啟動參數中監聽的端口號。
在安全的內部網絡環境中可以關閉防火牆服務:
# systemctl disable firewalld
# systemctl stop firewalld
另外,建議在主機上禁用SELinux,讓容器可以讀取主機文件系統:
# setenforce 0
或修改系統文件/etc/sysconfig/selinux,將SELINUX=enforcing修改成SELINUX=disabled,然后重啟Linux。
2.2 使用kubeadm工具快速安裝Kubernetes集群
最簡單的方法是使用yum install kubernetes命令安裝Kubernetes集群,
但仍需修改各組件的啟動參數,才能完成對Kubernetes集群的配置,整個過程比較復雜,也容易出錯。
Kubernetes從1.4版本開始引入了命令行工具kubeadm,致力於簡化集群的安裝過程,並解決Kubernetes集群的高可用問題。
在Kubernetes 1.13版本中,kubeadm工具進入GA階段,宣稱已經為生產環境應用准備就緒。
本節先講解基於kubeadm的安裝過程(以CentOS 7為例)。
2.2.1 安裝kubeadm和相關工具
首先配置yum源,官方yum源的地址為https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64。
如果無法訪問官方yum源的地址,則也可以使用國內的一個yum源,地址為http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/,
yum源的配置文件/etc/yum.repos.d/kubernetes.repo的內容如下:
[kubernetes]
name=Kubernetes Rspository
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
然后運行yum install命令安裝kubeadm和相關工具:
# yum install -y kubectl kubeadm kubectl --disableexcludes=kubernetes
運行下面的命令,啟動Docker服務(如果已安裝Docker,則無須再次啟動)和kubelet服務,並設置為開機自動啟動:
# systemctl enable docker && systemctl start docker
# systemctl enable kubelet && systemctl start kubelet
2.2.2 kubeadm config
kubeadm已經進入GA階段,其控制面初始化和加入節點步驟都支持大量的可定制內容,因此kubeadm還提供了配置文件功能用於復雜定制。
同時,kubeadm將配置文件以ConfigMap的形式保存到集群之中,便於后續的查詢和升級工作。
kubeadm config子命令提供了對這一組功能的支持:
kubeadm config upload from-file:由配置文件上傳到集群中生成ConfigMap。
kubeadm config upload from-flags:由配置參數生成ConfigMap。
kubeadm config view:查看當前集群中的配置值。
kubeadm config print init-defaults:輸出kubeadm init默認參數文件的內容。
kubeadm config print join-defaults:輸出kubeadm join默認參數文件的內容。
kubeadm config migrate:在新舊版本之間進行配置轉換。
kubeadm config images list:列出所需的鏡像列表。
kubeadm config images pull:拉取鏡像到本地。
例如,執行kubeadm config print init-defaults,可以取得默認的初始化參數文件:
# kubeadm config print init-defaults > init.default.yaml
對生成的文件進行編輯,可以按需生成合適的配置。
例如,若需要定制鏡像倉庫的地址,以及Pod的地址范圍,則可以使用如下配置:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
imageRepository: docker.io/dustise
kubernetesVersion: v1.14.0
networking:
podSubnet: "192.168.0.0/16"
將上面的內容保存為init-config.yaml備用。
2.2.3 下載Kubernetes的相關鏡像
為了從國內的鏡像托管站點獲得鏡像加速支持,建議修改Docker的配置文件,增加Registry Mirror參數,將鏡像配置寫入配置參數中,
例如echo '{"registry-mirrors":["https://registry.docker-cn.com"]}' > /etc/docker/daemon.json,然后重啟Docker服務。
使用config images pull子命令下載所需鏡像,例如:
# kubeadm config images pull --config=init-config.yaml
在鏡像下載完成之后,就可以進行安裝了。
2.2.4 運行kubeadm init命令安裝Master
至此,准備工作已就緒,執行kubeadm init命令即可一鍵安裝Kubernetes的Master。
在開始之前需要注意:
kubeadm的安裝過程不涉及網絡插件(CNI)的初始化,因此kubeadm初步安裝完成的集群不具備網絡功能,任何Pod包括自帶的CoreDNS都無法正常工作。
而網絡插件的安裝往往對kubeadm init命令的參數有一定的要求。
例如,安裝Calico插件時需要指定--pod-network-cidr=192.168.0.0/16,
詳情可參考https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network。
接下來使用kubeadm init命令,使用前面創建的配置文件進行集群控制面的初始化:
# kubeadm init --config=init-config.yaml
運行后,控制台將輸出如下內容:
等待一段時間后,Kubernetes的Master安裝成功,顯示如下信息:
"kubeadm join 10.211.55.30:6443 --token ah9koe.nvuvz2v60iam0e0d"
按照提示執行下面的命令,復制配置文件到普通用戶的home目錄下:
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo shown $(id -u):$(id -g) $HOME/.kube/config
這樣就在Master上安裝了Kubernetes,但在集群內還是沒有可用的工作Node,並缺乏對容器網絡的配置。
這里需要注意kubeadm init命令執行完成后的最后幾行提示信息,其中包含加入節點的指令(kubeadm join)和所需的Token。
此時可以用kubectl命令驗證在2.2.2節中提到的ConfigMap:
# kubectl get -n kube-system configmap
可以看到其中生成了名為kubeadm-config的ConfigMap對象。
2.2.5 安裝Node,加入集群
對於新節點的添加,系統准備和Kubernetes yum源的配置過程是一致的,在Node主機上執行下面的安裝過程。
(1)安裝kubeadm和相關工具:
# yum install -y kubectl kubeadm kubectl --disableexcludes=kubernetes
運行下面的命令啟動Docker服務與kubelet服務,並將其設置為開機自啟動:
# systemctl enable docker && systemctl start docker
# systemctl enable kubelet && systemctl start kubelet
(2)為kubeadm命令生成配置文件。創建文件join-config.yaml,內容如下:
apiVersion: kubeadm.k8s.io/v1beta1
kind: JoinConfiguration
discovery:
bootstrapToken:
apiServerEndpoint: 10.211.55.30:6443
token: ah9koe.nvuvz2v60iam0e0d
unsafeSkipCAVerification: true
tlsBootstrapToken: ah9koe.nvuvz2v60iam0e0d
其中,apiServerEndpoint的值來自Master服務器的地址,token和tlsBootstrapToken的值就來自於使用kubeadm init安裝Master的最后一行提示信息。
(3)執行kubeadm join命令,將本Node加入集群:
# kubeadm join --config=join-config.yaml
kubeadm在Master上也安裝了kubelet,在默認情況下並不參與工作負載。
如果希望安裝一個單機All-In-One的Kubernetes環境,則可以執行下面的命令(刪除Node的Label“node-role.kubernetes.io/master”),讓Master成為一個Node:
# kubectl taint nodes --all node-role.kubernetes.io/master-
2.2.6 安裝網絡插件
執行kubectl get nodes命令,會發現Kubernetes提示Master為NotReady狀態,這是因為還沒有安裝CNI網絡插件:
# kubectl get nodes
下面根據kubeadm的提示安裝CNI網絡插件。
對於CNI網絡插件,可以有許多選擇,請參考https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network的說明。
例如,選擇weave插件,執行下面的命令即可一鍵完成安裝:
# kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
2.2.7 驗證Kubernetes集群是否安裝完成
執行下面的命令,驗證Kubernetes集群的相關Pod是否都正常創建並運行:
# kubectl get pods --all-namespaces
如果發現有狀態錯誤的Pod,則可以執行kubectl --namespace=kube-system describe pod <pod_name>來查看錯誤原因,常見的錯誤原因是鏡像沒有下載完成。
至此,通過kubeadm工具就實現了Kubernetes集群的快速搭建。
如果安裝失敗,則可以執行kubeadm reset命令將主機恢復原狀,重新執行kubeadm init命令,再次進行安裝。
2.3 以二進制文件方式安裝Kubernetes集群
本節以二進制文件方式安裝Kubernetes集群,並對每個組件的配置進行詳細說明。
從Kubernetes發布官網https://github.com/kubernetes/kubernetes/releases找到對應的版本號,
單擊CHANGELOG,找到已編譯好的二進制文件的下載頁面,如圖2.1和圖2.2所示。
本書基於Kubernetes 1.14版本進行說明。
在壓縮包kubernetes.tar.gz內包含了Kubernetes的服務程序文件、文檔和示例;在壓縮包kubernetes-src.tar.gz內則包含了全部源代碼。
也可以直接下載Server Binaries中的kubernetes-server-linux-amd64.tar.gz文件,其中包含了Kubernetes需要運行的全部服務程序文件。
主要的服務程序文件列表如表2.2所示。
Kubernetes的主要服務程序都可以通過直接運行二進制文件加上啟動參數完成運行。
在Kubernetes的Master上需要部署etcd、kube-apiserver、kube-controller-manager、kube-scheduler服務進程,
在工作Node上需要部署docker、kubelet和kube-proxy服務進程。
將Kubernetes的二進制可執行文件復制到/usr/bin目錄下,
然后在/usr/lib/system/system目錄下為各服務創建systemd服務配置文件(完整的systemd系統知識請參考Linux的相關手冊),這樣就完成了軟件的安裝。
要使Kubernetes正常工作,需要詳細配置各個服務的啟動參數。
下面主要介紹各服務最主要的啟動參數,每個服務完整啟動的參數說明詳見2.8節。
2.3.1 Master上的etcd、kube-apiserver、kube-controller-manager、kube-scheduler服務
1.etcd服務
etcd服務作為Kubernetes集群的主數據庫,在安裝Kubernetes各服務之前需要首先安裝和啟動。
從GitHub官網(https://github.com/coreos/etcd/releases)下載etcd二進制文件,將etcd和etcdctl文件復制到/usr/bin目錄。
設置systemd服務配置文件/usr/lib/systemd/system/etcd.service:
[Unit]
Description=Etcd Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
[Install]
WantedBy=multi-user.target
其中,WorkingDirectory(/var/lib/etcd/)表示etcd數據保存的目錄,需要在啟動etcd服務之前創建。
配置文件/etc/etcd/etcd.conf通常不需要特別的參數設置(詳細的參數配置內容參見官方文檔),etcd默認使用http://127.0.0.1:2379地址供客戶端連接。
配置完成后,通過systemctl start命令啟動etcd服務。同時,使用systemctl enable命令將服務加入開機啟動列表中:
# systemctl daemon-reload
# systemctl enable etcd.service
# systemctl start etcd.service
通過執行etcdctl cluster-health,可以驗證etcd是否正確啟動:
# etcdctl cluster health
2.kube-apiserver服務
將kube-apiserver、kube-controller-manager和kube-scheduler文件復制到/usr/bin目錄。
設置systemd服務配置文件/usr/lib/systemd/system/kube-apiserver.service,內容如下:
[Unit]
Description=Kubernetes API Server
Decumentation=https://github.com/GoogleCloudPlatform/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
配置文件/etc/kubernetes/apiserver的內容包括了kube-apiserver的全部啟動參數,主要的配置參數在變量KUBE_API_ARGS中指定。
# cat /etc/kubernetes/apiserver
對啟動參數說明如下。
--etcd-servers:指定etcd服務的URL。
--storage-backend:指定etcd的版本,從Kubernetes 1.6開始,默認為etcd 3。
注意,在Kubernetes 1.6之前的版本中沒有這個參數,kube-apiserver默認使用etcd 2,
對於正在運行的1.5或舊版本的Kubernetes集群,etcd提供了數據升級方案,詳見etcd文檔(https://coreos.com/etcd/docs/latest/upgrades/upgrade_3_0.html)。
--insecure-bind-address:API Server綁定主機的非安全IP地址,設置0.0.0.0表示綁定所有IP地址。
--insecure-port:API Server綁定主機的非安全端口號,默認為8080。
--service-cluster-ip-range:Kubernetes集群中Service的虛擬IP地址范圍,以CIDR格式表示,例如169.169.0.0/16,該IP范圍不能與物理機的IP地址有重合。
--service-node-port-range:Kubernetes集群中Service可使用的物理機端口號范圍,默認值為30000~32767。
--enable-admission-plugins:Kubernetes集群的准入控制設置,各控制模塊以插件的形式依次生效。
--logtostderr:設置為false表示將日志寫入文件,不寫入stderr。
--log-dir:日志目錄。
--v:日志級別。
3.kube-controller-manager服務
kube-controller-manager服務依賴於kube-apiserver服務,
設置systemd服務配置文件/usr/lib/systemd/system/kube-controller-manager.service,內容如下:
[Unit]
Description=Kubernetes Controller Manager
Decumentation=https://github.com/GoogleCloudPlatform/kubernetes
After=kube-apiserver.service
Requires=kube-apiserver.service
[Service]
EnvironmentFile=/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
配置文件/etc/kubernetes/controller-manager的內容包含了kube-controller-manager的全部啟動參數,
主要的配置參數在變量KUBE_CONTROLLER_MANAGER_ARGS中指定:
# cat /etc/kubernetes/controller-manager
對啟動參數說明如下。
--kubeconfig:設置與API Server連接的相關配置,例如:--kubeconfig=/etc/kubernetes/kubeconfig
--logtostderr:設置為false表示將日志寫入文件,不寫入stderr。
--log-dir:日志目錄。
--v:日志級別。
4.kube-scheduler服務
kube-scheduler服務也依賴於kube-apiserver服務,
設置systemd服務配置文件/usr/lib/systemd/system/kube-scheduler.service,內容如下:
[Unit]
Description=Kubernetes Scheduler
Decumentation=https://github.com/GoogleCloudPlatform/kubernetes
After=kube-apiserver.service
Requires=kube-apiserver.service
[Service]
EnvironmentFile=/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
配置文件/etc/kubernetes/scheduler的內容包括了kube-scheduler的全部啟動參數,
主要的配置參數在變量KUBE_SCHEDULER_ARGS中指定:
# cat /etc/kubernetes/scheduler
對啟動參數說明如下。
--kubeconfig:設置與API Server連接的相關配置,可以與kube-controller-manager使用的kubeconfig文件相同。
--logtostderr:設置為false表示將日志寫入文件,不寫入stderr。
--log-dir:日志目錄。
--v:日志級別。
配置完成后,執行systemctl start命令按順序啟動這3個服務,同時,使用systemctl enable命令將服務加入開機啟動列表中:
# systemctl daemon-reload
# systemctl enable kube-apiserver.service
# systemctl start kube-apiserver.service
# systemctl enable kube-controller-manager
# systemctl start kube-controller-manager
# systemctl enable kube-scheduler
# systemctl start kube-scheduler
通過systemctl status <service_name>驗證服務的啟動狀態,running表示啟動成功。
至此,Master上所需的服務就全部啟動完成了。
2.3.2 Node上的kubelet、kube-proxy服務
在工作Node上需要預先安裝好Docker Daemon並且正常啟動。
Docker的安裝和啟動詳見Docker官網http://www.docker.com的說明文檔。
1.kubelet服務
kubelet服務依賴於Docker服務,設置systemd服務配置文件/usr/lib/systemd/system/kubelet.service,內容如下:
[Unit]
Description=Kubernetes Kubelet Server
Decumentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet $KUBELET_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
其中,WorkingDirectory表示kubelet保存數據的目錄,需要在啟動kubelet服務之前創建。
配置文件/etc/kubernetes/kubelet的內容包括了kubelet的全部啟動參數,主要的配置參數在變量KUBELET_ARGS中指定:
# cat /etc/kubernetes/kubelet
對啟動參數說明如下。
--kubeconfig:設置與API Server連接的相關配置,可以與kube-controller-manager使用的kubeconfig文件相同。
--hostname-override:設置本Node的名稱。
--logtostderr:設置為false表示將日志寫入文件,不寫入stderr。
--log-dir:日志目錄。
--v:日志級別。
2.kube-proxy服務
kube-proxy服務依賴於network服務,設置systemd服務配置文件/usr/lib/systemd/system/kube-proxy.service,內容如下:
[Unit]
Description=Kubernetes Kube-Proxy Server
Decumentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
Requires=network.service
[Service]
EnvironmentFile=/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy $KUB_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
配置文件/etc/kubernetes/proxy的內容包括了kube-proxy的全部啟動參數,主要的配置參數在變量KUBE_PROXY_ARGS中指定:
# cat /etc/kubernetes/proxy
對啟動參數說明如下。
--kubeconfig:設置與API Server連接的相關配置,可以與kube-controller-manager使用的kubeconfig文件相同。
--logtostderr:設置為false表示將日志寫入文件,不寫入stderr。
--log-dir:日志目錄。
--v:日志級別。
配置完成后,通過systemctl啟動kubelet和kube-proxy服務:
# systemctl daemon-reload
# systemctl enable kubelet.service
# systemctl start kubelet.service
# systemctl enable kube-proxy
# systemctl start kube-proxy
kubelet默認采用向Master自動注冊本Node的機制,在Master上查看各Node的狀態,狀態為Ready表示Node已經成功注冊並且狀態為可用:
# kubectl get nodes
等所有Node的狀態都為Ready之后,一個Kubernetes集群就啟動完成了。
接下來可以創建Pod、Deployment、Service等資源對象來部署容器應用了。
2.4 Kubernetes集群的安全設置
2.4.1 基於CA簽名的雙向數字證書認證方式
在一個安全的內網環境中,Kubernetes的各個組件與Master之間可以通過kube-apiserver的非安全端口http://<kube-apiserver-ip>:8080進行訪問。
但如果API Server需要對外提供服務,或者集群中的某些容器也需要訪問API Server以獲取集群中的某些信息,則更安全的做法是啟用HTTPS安全機制。
Kubernetes提供了基於CA簽名的雙向數字證書認證方式和簡單的基於HTTP Base或Token的認證方式,其中CA證書方式的安全性最高。
本節先介紹如何以CA證書的方式配置Kubernetes集群,
要求Master上的kube-apiserver、kube-controller-manager、kube-scheduler進程及各Node上的kubelet、kube-proxy進程進行CA簽名雙向數字證書安全設置。
基於CA簽名的雙向數字證書的生成過程如下:
(1)為kube-apiserver生成一個數字證書,並用CA證書簽名。
(2)為kube-apiserver進程配置證書相關的啟動參數,包括CA證書(用於驗證客戶端證書的簽名真偽)、自己的經過CA簽名后的證書及私鑰。
(3)為每個訪問Kubernetes API Server的客戶端(如kube-controller-manager、kube-scheduler、kubelet、kube-proxy及調用API Server的客戶端程序kubectl等)進程
都生成自己的數字證書,也都用CA證書簽名,在相關程序的啟動參數里增加CA證書、自己的證書等相關參數。
1.設置kube-apiserver的CA證書相關的文件和啟動參數
使用OpenSSL工具在Master服務器上創建CA證書和私鑰相關的文件:
# openssl genrsa -out ca.key 2048
# openssl req -x509 -new -nodes -key ca.key -subj "/CN=k8s-master" -days 5000 -out ca.crt
# openssl genrsa -out server.key 2048
注意:在生成ca.crt時,-subj參數中“/CN”的值為Master主機名。
准備master_ssl.cnf文件,該文件用於x509 v3版本的證書。在該文件中主要需要設置Master服務器的hostname(k8s-master)、IP地址(192.168.18.3),
以及Kubernetes Master Service的虛擬服務名稱(kubernetes.default等)和該虛擬服務的ClusterIP地址(169.169.0.1)。
master_ssl.cnf文件的示例如下:
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = k8s-master
IP.1 = 169.169.0.1
IP.2 = 192.168.18.3
基於master_ssl.cnf創建server.csr和server.crt文件。在生成server.csr時,-subj參數中“/CN”的值需為Master的主機名:
# openssl req -new -key server.key -subj "/CN=k8s-master" -config master_ssl.cnf -out server.csr
# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.cnf -out server.crt
在全部執行完后會生成6個文件:ca.crt、ca.key、ca.srl、server.crt、server.csr、server.key。
將這些文件復制到一個目錄下(例如/var/run/kubernetes/),然后設置kube-apiserver的三個啟動參數“--client-ca-file”“--tls-cert-file”和“--tls-private-key-file”,
分別代表CA根證書文件、服務端證書文件和服務端私鑰文件:
--client-ca-file=/var/run/kubernetes/ca.crt
--tls-cert-file=/var/run/kubernetes/server.crt
--tls-private-key-file=/var/run/kubernetes/server.key
同時,可以關閉非安全端口(設置--insecure-port=0),設置安全端口為6443(默認值):
--insecure-port=0
--secure-port=6443
最后重啟kube-apiserver服務。
2.設置kube-controller-manager的客戶端證書、私鑰和啟動參數
代碼如下:
# openssl genrsa -out cs_client.key 2048
# openssl req -new -key ca_client.key -subj "/CN=k8s-master" -out cs_client.csr
# openssl x509 -req -in ca_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out cs_client.crt -days 5000
其中,在生成cs_client.crt時,-CA參數和-CAkey參數使用的是API Server的ca.crt和ca.key文件。
然后將這些文件復制到一個目錄下(例如/var/run/kubernetes/)。
接下來創建/etc/kubernetes/kubeconfig文件(kube-controller-manager與kube-scheduler共用),配置客戶端證書等相關參數,內容如下。
apiVersion: v1
kind: Config
users:
- name: controllermanager
user:
client-certificate: /var/run/kubernetes/cs_client.crt
client-key: /var/run/kubernetes/cs_client.key
clusters:
- name: local
cluster:
certificate-authority: /var/run/kubernetes/ca.crt
server: https://192.168.18.3:6443
contexts:
- context:
cluster: local
user: controllermanager
name: my-context
current-context: my-context
然后設置kube-controller-manager服務的啟動參數:
--service-account-key-file=/var/run/kubernetes/server.key
--root-ca-file=/var/run/kubernetes/ca.crt
--kubeconfig=/etc/kubernetes/kubeconfig
最后重啟kube-controller-manager服務。
3.設置kube-scheduler啟動參數
kube-scheduler復用上一步kube-controller-manager創建的客戶端證書,配置啟動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
重啟kube-scheduler服務。
4.設置每個Node上kubelet的客戶端證書、私鑰和啟動參數
首先,復制kube-apiserver的ca.crt和ca.key文件到Node上,
在生成kubelet_client.crt時-CA參數和-CAkey參數使用的是API Server的ca.crt和ca.key文件;
在生成kubelet_client.csr時,將-subj參數中的“/CN”設置為本Node的IP地址:
# openssl genrsa -out kubelet_client.key 2048
# openssl req -new -key kubelet_client.key -subj "/CN=本Node的IP地址" -out kubelet_client.csr
# openssl x509 -req -in kubelet_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet_client.crt -days 5000
將這些文件復制到一個目錄下(例如/etc/kubernetes/ssl_keys/)。
接下來創建/etc/kubernetes/kubeconfig文件(kubelet和kube-proxy進程共用),配置客戶端證書等相關參數,內容如下:
apiVersion: v1
kind: Config
users:
- name: kubelet
user:
client-certificate: /etc/kubernetes/ssl_keys/kubelet_client.crt
client-key: /etc/kubernetes/ssl_keys/kubelet_client.key
clusters:
- name: local
cluster:
certificate-authority: /etc/kubernetes/ssl_keys/ca.crt
server: https://192.168.18.3:6443
contexts:
- context:
cluster: local
user: kubelet
name: my-context
current-context: my-context
然后設置kubelet服務的啟動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
最后重啟kubelet服務。
5.設置kube-proxy的啟動參數
kube-proxy復用上一步kubelet創建的客戶端證書,配置啟動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
重啟kube-proxy服務。
至此,一個基於CA的雙向數字證書認證的Kubernetes集群環境就搭建完成了。
6.設置kubectl客戶端使用安全方式訪問API Server
在使用kubectl對Kubernetes集群進行操作時,默認使用非安全端口8080對API Server進行訪問,也可以設置為安全訪問API Server的模式,
需要設置3個證書相關的參數“—certificate-authority”“--client-certificate”和“--client-key”,分別表示用於CA授權的證書、客戶端證書和客戶端密鑰。
--certificate-authority:使用為kube-apiserver生成的ca.crt文件。
--client-certificate:使用為kube-controller-manager生成的cs_client.crt文件。
--client-key:使用為kube-controller-manager生成的cs_client.key文件。
同時,指定API Server的URL地址為HTTPS安全地址(例如https://k8s-master:443),最后輸入需要執行的子命令,即可對API Server進行安全訪問了:
# kubectl --server=https://192.168.18.3:6443
--certificate-authority=/etc/kubernetes/ssl_keys/ca.crt
--client-certificate=/etc/kubernetes/ssl_keys/cs_client.crt
--client-key=/etc/kubernetes/ssl_keys/cs_client.key get nodes
2.4.2 基於HTTP Base或Token的簡單認證方式
除了提供了基於CA的雙向數字證書認證方式,Kubernetes也提供了基於HTTP Base或Token的簡單認證方式。
各組件與API Server之間的通信方式仍然采用HTTPS,但不使用CA數字證書。
采用基於HTTP Base或Token的簡單認證方式時,API Server對外暴露HTTPS端口,客戶端提供用戶名、密碼或Token來完成認證過程。
需要說明的是,kubectl命令行工具比較特殊,它同時支持CA雙向認證和簡單認證兩種模式與API Server通信,
其他客戶端組件只能配置為雙向安全認證或非安全模式與API Server通信。
1.基於HTTP Base認證的配置過程
(1)創建包括用戶名、密碼和UID的文件basic_auth_file,放置在合適的目錄下,例如/etc/kuberntes目錄。
需要注意的是,這是一個純文本文件,用戶名、密碼都是明文。
# vi /etc/kuberntes/basic_auth_file
admin,admin,1
system,system,2
(2)設置kube-apiserver的啟動參數“--basic-auth-file”,使用上述文件提供安全認證:
--secure-port=6443
--basic-auth-file=/etc/kuberntes/basic_auth_file
然后,重啟API Server服務。
(3)使用kubectl通過指定的用戶名和密碼來訪問API Server:
# kubectl --server=https://192.168.18.3.:6443 --username=admin --password=admin --insecure-skip-tls-verify=true get nodes
2.基於Token認證的配置過程
(1)創建包括用戶名、密碼和UID的文件token_auth_file,放置在合適的目錄下,例如/etc/kuberntes目錄。
需要注意的是,這是一個純文本文件,用戶名、密碼都是明文。
# vi /etc/kuberntes/token_auth_file
admin,admin,1
system,system,2
(2)設置kube-apiserver的啟動參數“--token-auth-file”,使用上述文件提供安全認證:
--secure-port=6443
--token-auth-file=/etc/kuberntes/token_auth_file
然后,重啟API Server服務。
(3)用curl驗證和訪問API Server:
# curl -k --header "Authorization:Bearer admin" https://192.168.18.3:6443/version {}
2.5 Kubernetes集群的網絡配置
在多個Node組成的Kubernetes集群內,跨主機的容器間網絡互通是Kubernetes集群能夠正常工作的前提條件。
Kubernetes本身並不會對跨主機的容器網絡進行設置,這需要額外的工具來實現。
除了谷歌公有雲GCE平台提供的網絡設置,一些開源的工具包括Flannel、Open vSwitch、Weave、Calico等都能夠實現跨主機的容器間網絡互通。
隨着CNI網絡模型的逐漸成熟,Kubernetes將優先使用CNI網絡插件打通跨主機的容器網絡。
具體的網絡原理及主流開源網絡工具的原理和配置詳見第7章的說明。
2.6 內網中的Kubernetes相關配置
Kubernetes在能夠訪問Internet網絡的環境中使用起來非常方便:
一方面,在docker.io和gcr.io網站中已經存在了大量官方制作的Docker鏡像;
另一方面,GCE、AWS提供的雲平台已經成熟,用戶通過租用一定的空間來部署Kubernetes集群也很簡便。
但是,許多企業內部由於安全原因無法訪問Internet,
需要通過創建一個內部的私有Docker Registry,並修改一些Kubernetes的配置,來啟動內網中的Kubernetes集群。
2.6.1 Docker Private Registry(私有Docker鏡像庫)
使用Docker提供的Registry鏡像創建一個私有鏡像倉庫。
詳細的安裝步驟請參考Docker的官方文檔https://docs.docker.com/registry/deploying/。
2.6.2 kubelet配置
由於在Kubernetes中是以Pod而不是以Docker容器為管理單元的,在kubelet創建Pod時,還通過啟動一個名為k8s.gcr.io/pause:3.1的鏡像來實現Pod的概念。
該鏡像存在於谷歌鏡像庫k8s.gcr.io中,需要通過一台能夠連上Internet的服務器將其下載,導出文件,再push到私有Docker Registry中。
之后,可以給每個Node的kubelet服務都加上啟動參數--pod-infra-container-image,指定為私有Docker Registry中pause鏡像的地址。
例如:# cat /etc/kubernetes/kubelet
kubelet_args="--kubeconfig=/etc/kubernetes/kubeconfig --hostname-override=192.168.18.3 --log-dir=/var/log/kubernets --v=0 --pod-infra-container-image=myregistry/pause:3.1"
然后重啟kubelet服務:
# systemctl restart kubelet
通過以上設置就在內網環境中搭建了一個企業內部的私有容器雲平台。
2.7 Kubernetes的版本升級
2.7.1 二進制升級
Kubernetes的版本升級需要考慮到不要讓當前集群中正在運行的容器受到影響。
應對集群中的各Node逐個進行隔離,然后等待在其上運行的容器全部執行完成,再更新該Node上的kubelet和kube-proxy服務,將全部Node都更新完成后,再更新Master的服務。
通過官網獲取最新版本的二進制包kubernetes.tar.gz,解壓后提取服務的二進制文件。
逐個隔離Node,等待在其上運行的全部容器工作完成后,更新kubelet和kube-proxy服務文件,然后重啟這兩個服務。
更新Master的kube-apiserver、kube-controller-manager、kube-scheduler服務文件並重啟。
2.7.2 使用kubeadm進行集群升級
kubeadm提供了upgrade命令用於對kubeadm安裝的Kubernetes集群進行升級。
這一功能提供了從1.10到1.11、從1.11到1.12、從1.12到1.13及從1.13到1.14的升級能力,這里試用一下從1.13到1.14的升級。
開始之前需要注意:
雖然kubeadm的升級不會觸及工作負載,但還是要在升級之前做好備份。
升級過程可能會因為Pod的變化而造成容器重啟。
繼續以CentOS 7環境為例,首先需要升級的是kubeadm:
# yum install -y kubeadm-1.14.0 --disableexcludes=kubernetes
查看kubeadm的版本:
# kubeadm version
接下來查看kubeadm的升級計划:
# kubeadm upgrade plan
會出現預備升級的內容描述:
Running pre-flight check.
[upgrade/versions] kubeadm version: v1.14.0
按照任務指引進行升級:
# kubeadm upgrade apply 1.14.0
[upgrade/confirm] Are you sure you want to proceed with the upgrade? [y/N]
輸入“y”,確認之后,開始進行升級。
運行完成之后,再次查詢版本:
# kubectl version
可以看到,雖然kubectl還是1.13.2,服務端的控制平面已經升級到了1.14.0,但是查看Node版本,會發現Node版本還是滯后的:
# kubectl get nodes
然后可以對節點配置進行升級:
# kubeadm upgrade node config --kubelet-version 1.14.0
接下來,按照和二進制升級一樣的步驟將kubelct升級,這樣就完成了集群的整體升級:
# kubectl get nodes
2.8 Kubernetes核心服務配置詳解
2.1節對Kubernetes各服務啟動進程的關鍵配置參數進行了簡要說明,實際上Kubernetes的每個服務都提供了許多可配置的參數。
這些參數涉及安全性、性能優化及功能擴展(Plugin)等方方面面。
全面理解和掌握這些參數的含義和配置,對Kubernetes的生產部署及日常運維都有很大的幫助。
每個服務的可用參數都可以通過運行“cmd --help”命令進行查看,其中cmd為具體的服務啟動命令,
例如kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy等。
另外,可以通過在命令的配置文件(例如/etc/kubernetes/kubelet等)中添加“--參數名=參數取值”語句來完成對某個參數的配置。
本節將對Kubernetes所有服務的參數進行全面介紹,為了方便學習和查閱,對每個服務的參數都用一個小節進行詳細說明。
2.8.1 公共配置參數
公共配置參數適用於所有服務,如表2.3所示的參數可用於kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy。
本節對這些參數進行統一說明,不再在每個服務的參數列表中列出。
表2.3 公共配置參數表
2.8.2 kube-apiserver啟動參數
對kube-apiserver啟動參數的詳細說明如表2.4所示。
表2.4 對kube-apiserver啟動參數的詳細說明
2.8.3 kube-controller-manager啟動參數
對kube-controller-manager啟動參數的詳細說明如表2.5所示。
表2.5 對kube-controller-manager啟動參數的詳細說明
2.8.4 kube-scheduler啟動參數
對kube-scheduler啟動參數的詳細說明如表2.6所示。
表2.6 對kube-scheduler啟動參數的詳細說明
2.8.5 kubelet啟動參數
對kubelet啟動參數的詳細說明如表2.7所示。
表2.7 對kubelet啟動參數的詳細說明
2.8.6 kube-proxy啟動參數
對kube-proxy啟動參數的詳細說明見表2.8。
表2.8 對kube-proxy啟動參數的詳細說明
2.9 CRI(容器運行時接口)詳解
歸根結底,Kubernetes Node(kubelet)的主要功能就是啟動和停止容器的組件,我們稱之為容器運行時(Container Runtime),其中最知名的就是Docker了。
為了更具擴展性,Kubernetes從1.5版本開始就加入了容器運行時插件API,即Container Runtime Interface,簡稱CRI。
2.9.1 CRI概述
每個容器運行時都有特點,因此不少用戶希望Kubernetes能夠支持更多的容器運行時。
Kubernetes從1.5版本開始引入了CRI接口規范,通過插件接口模式,Kubernetes無須重新編譯就可以使用更多的容器運行時。
CRI包含Protocol Buffers、gRPC API、運行庫支持及開發中的標准規范和工具。
Docker的CRI實現在Kubernetes 1.6中被更新為Beta版本,並在kubelet啟動時默認啟動。
可替代的容器運行時支持是Kubernetes中的新概念。
在Kubernetes 1.3發布時,rktnetes項目同時發布,讓rkt容器引擎成為除Docker外的又一選擇。
然而,不管是Docker還是rkt,都用到了kubelet的內部接口,同kubelet源碼糾纏不清。
這種程度的集成需要對kubelet的內部機制有非常深入的了解,還會給社區帶來管理壓力,這就給新生代容器運行時造成了難於跨越的集成壁壘。
CRI接口規范試圖用定義清晰的抽象層清除這一壁壘,讓開發者能夠專注於容器運行時本身。
在通向插件式容器支持及建設健康生態環境的路上,這是一小步,也是很重要的一步。
2.9.2 CRI的主要組件
kubelet使用gRPC框架通過UNIX Socket與容器運行時(或CRI代理)進行通信。
在這個過程中kubelet是客戶端,CRI代理(shim)是服務端,如圖2.3所示。
Protocol Buffers API包含兩個gRPC服務:ImageService和RuntimeService。
ImageService提供了從倉庫拉取鏡像、查看和移除鏡像的功能。
RuntimeService負責Pod和容器的生命周期管理,以及與容器的交互(exec/attach/port-forward)。
rkt和Docker這樣的容器運行時可以使用一個Socket同時提供兩個服務,
在kubelet中可以用--container-runtime-endpoint和--image-service-endpoint參數設置這個Socket。
2.9.3 Pod和容器的生命周期管理
Pod由一組應用容器組成,其中包含共有的環境和資源約束。在CRI里,這個環境被稱為PodSandbox。
Kubernetes有意為容器運行時留下一些發揮空間,它們可以根據自己的內部實現來解釋PodSandbox。
對於Hypervisor類的運行時,PodSandbox會具體化為一個虛擬機。其他例如Docker,會是一個Linux命名空間。
在v1alpha1 API中,kubelet會創建Pod級別的cgroup傳遞給容器運行時,並以此運行所有進程來滿足PodSandbox對Pod的資源保障。
在啟動Pod之前,kubelet調用RuntimeService.RunPodSandbox來創建環境。這一過程包括為Pod設置網絡資源(分配IP等操作)。
PodSandbox被激活之后,就可以獨立地創建、啟動、停止和刪除不同的容器了。
kubelet會在停止和刪除PodSandbox之前首先停止和刪除其中的容器。
kubelet的職責在於通過RPC管理容器的生命周期,實現容器生命周期的鈎子,存活和健康監測,以及執行Pod的重啟策略等。
RuntimeService服務包括對Sandbox和Container操作的方法,下面的偽代碼展示了主要的RPC方法。
2.9.4 面向容器級別的設計思路
眾所周知,Kubernetes的最小調度單元是Pod,它曾經可能采用的一個CRI設計就是復用Pod對象,使得容器運行時可以自行實現控制邏輯和狀態轉換,
這樣一來,就能極大地簡化API,讓CRI能夠更廣泛地適用於多種容器運行時。但是經過深入討論之后,Kubernetes放棄了這一想法。
首先,kubelet有很多Pod級別的功能和機制(例如crash-loop backoff機制),如果交給容器運行時去實現,則會造成很重的負擔;
其次,且更重要的是,Pod標准還在快速演進中,很多新功能(如初始化容器)都是由kubelet完成管理的,無須交給容器運行時實現。
CRI選擇了在容器級別進行實現,使得容器運行時能夠共享這些通用特性,以獲得更快的開發速度。
這並不意味着設計哲學的改變—kubelet要負責、保證容器應用的實際狀態和聲明狀態的一致性。
Kubernetes為用戶提供了與Pod及其中的容器進行交互的功能(kubectl exec/attach/port- forward)。
kubelet目前提供了兩種方式來支持這些功能。
(1)調用容器的本地方法。
(2)使用Node上的工具(例如nsenter及socat)。
因為多數工具都假設Pod用Linux namespace做了隔離,因此使用Node上的工具並不是一種容易移植的方案。
在CRI中顯式定義了這些調用方法,讓容器運行時進行具體實現。
下面的偽代碼顯示了Exec、Attach、PortForward這幾個調用需要實現的RuntimeService方法。
目前還有一個潛在問題是,kubelet處理所有的請求連接,使其有成為Node通信瓶頸的可能。
在設計CRI時,要讓容器運行時能夠跳過中間過程。
容器運行時可以啟動一個單獨的流式服務來處理請求(還能對Pod的資源使用情況進行記錄),並將服務地址返回給kubelet。
這樣kubelet就能反饋信息給API Server,使之可以直接連接到容器運行時提供的服務,並連接到客戶端。
2.9.5 嘗試使用新的Docker-CRI來創建容器
要嘗試新的Kubelet-CRI-Docker集成,只需為kubelet啟動參數加上--enable-cri=true開關來啟動CRI。
這個選項從Kubernetes 1.6開始已經作為kubelet的默認選項了。
如果不希望使用CRI,則可以設置--enable-cri=false來關閉這個功能。
查看kubelet的日志,可以看到啟用CRI和創建gRPC Server的日志。
創建一個Deployment:
# kubectl run nginx --image=nginx
查看Pod的詳細信息,可以看到將會創建沙箱(Sandbox)的Event:
# kubectl describe pod nginx
這表明kubelet使用了CRI接口來創建容器。
2.9.6 CRI的進展
目前已經有多款開源CRI項目可用於Kubernetes:Docker、CRI-O、Containerd、frakti(基於Hypervisor的容器運行時),
各CRI運行時的安裝手冊可參考官網https://kubernetes.io/docs/setup/cri/的說明。
2.10 kubectl命令行工具用法詳解
kubectl作為客戶端CLI工具,可以讓用戶通過命令行對Kubernetes集群進行操作。
本節對kubectl的子命令和用法進行詳細說明。
2.10.1 kubectl用法概述
kubectl命令行的語法如下:
# kubectl [command] [TYPE] [NAME] [flags]
其中,command、TYPE、NAME、flags的含義如下。
(1)command:子命令,用於操作Kubernetes集群資源對象的命令,例如create、delete、describe、get、apply等。
(2)TYPE:資源對象的類型,區分大小寫,能以單數、復數或者簡寫形式表示。例如以下3種TYPE是等價的。
# kubectl get pod pod1
# kubectl get pods pod1
# kubectl get po pod1
(3)NAME:資源對象的名稱,區分大小寫。如果不指定名稱,系統則將返回屬於TYPE的全部對象的列表,例如$ kubectl get pods將返回所有Pod的列表。
(4)flags:kubectl子命令的可選參數,例如使用“-s”指定API Server的URL地址而不用默認值。
kubectl可操作的資源對象類型及其縮寫如表2.9所示。
表2.9 kubectl可操作的資源對象類型及其縮寫
表2.9-1kubectl可操作的資源對象類型
在一個命令行中也可以同時對多個資源對象進行操作,以多個TYPE和NAME的組合表示,示例如下。
示例1:獲取多個Pod的信息:
# kubectl get pods pod1 pod2
示例2:獲取多種對象的信息:
# kubectl get pod/pod1 rc/rc1
示例3:同時應用多個YAML文件,以多個-f file參數表示:
# kubectl get pod -f pod1.yaml -f pod2.yaml
# kubectl create -f pod1.yaml -f rc1.yaml -f service1.yaml
2.10.2 kubectl子命令詳解
kubectl的子命令非常豐富,涵蓋了對Kubernetes集群的主要操作,包括資源對象的創建、刪除、查看、修改、配置、運行等。
詳細的子命令如表2.10所示。
表2.10 kubectl子命令詳解
2.10.3 kubectl參數列表
kubectl命令行的公共啟動參數如表2.11所示。
表2.11 kubectl命令行的公共啟動參數
每個子命令(如create、delete、get等)還有特定的flags參數,可以通過$ kubectl [command] --help命令進行查看。
2.10.4 kubectl輸出格式
kubectl命令可以用多種格式對結果進行顯示,輸出的格式通過-o參數指定:
# kubectl [command] [TYPE] [NAME] -o=<output_format>
根據不同子命令的輸出結果,可選的輸出格式如表2.12所示。
表2.12 kubectl命令的可選輸出格式列表
常用的輸出格式示例如下。
(1)顯示Pod的更多信息:
# kubectl get pod <pod-name> -o wide
(2)以YAML格式顯示Pod的詳細信息:
# kubectl get pod <pod-name> -o yaml
(3)以自定義列名顯示Pod的信息:
# kubectl get pod <pod-name> -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion
(4)基於文件的自定義列名輸出:
# kubectl get pod <pod-name> -o=custom-columns-file=template.txt
template.txt文件的內容為:
NAME RSRC
metadata.name metadata.resourceVersion
輸出結果為:
NAME RSRC
pod-name 52305
另外,可以將輸出結果按某個字段排序,通過--sort-by參數以jsonpath表達式進行指定:
# kubectl [command] [TYPE] [NAME] --sort-by=<jsonpath_exp>
例如,按照名稱進行排序:
# kubectl get pods --sort-by=.metadata.name
2.10.5 kubectl操作示例
本節將一些常用的kubectl操作作為示例進行說明。
1.創建資源對象
根據YAML配置文件一次性創建Service和RC:
# kubectl create -f my-service.yaml -f my-rc.yaml
根據<directory>目錄下所有.yaml、.yml、.json文件的定義進行創建:
# kubectl create -f <directory>
2.查看資源對象
查看所有Pod列表:
# kubectl get pods
查看RC和Service列表:
# kubectl get rc,service
3.描述資源對象
顯示Node的詳細信息:
# kubectl describe nodes <node-name>
顯示Pod的詳細信息:
# kubectl describe pods/<pod-name>
顯示由RC管理的Pod的信息:
# kubectl describe pods <rc-name>
4.刪除資源對象
基於pod.yaml定義的名稱刪除Pod:
# kubectl delete -f pod.yaml
刪除所有包含某個Label的Pod和Service:
# kubectl delete pods,services -l name=<label-name>
刪除所有Pod:
# kubectl delete pods --all
5.執行容器的命令
執行Pod的date命令,默認使用Pod中的第1個容器執行:
# kubectl exec <pod-name> date
指定Pod中的某個容器執行date命令:
# kubectl exec <pod-name> -c <container-name> date
通過bash獲得Pod中某個容器的TTY,相當於登錄容器:
# kubectl exec -it <pod-name> -c <container-name> /bin/bash
6.查看容器的日志
查看容器輸出到stdout的日志:
# kubectl logs <pod-name>
跟蹤查看容器的日志,相當於tail -f命令的結果:
# kubectl logs -f <pod-name> -c <container-name>
7.創建或更新資源對象
用法和kubectl create類似,邏輯稍有差異:如果目標資源對象不存在,則進行創建;否則進行更新。例如:
# kubectl apply -f app.yaml
8.在線編輯運行中的資源對象
可以使用kubectl edit命令編輯運行中的資源對象,例如使用下面的命令編輯運行中的一個Deployment:
# kubectl edit deploy nginx
在命令執行之后,會通過YAML格式展示該對象的定義和狀態,用戶可以對代碼進行編輯和保存,從而完成對在線資源的直接修改。
9.將Pod的開放端口映射到本地
將集群上Pod的80端口映射到本地的8888端口,在瀏覽器http://127.0.0.1:8888中就能夠訪問到容器提供的服務了:
# kubectl port-forward --address 0.0.0.0 \ pod/nginx-6ddbbc47fb-sfdcv 8888:80
10.在Pod和本地之間復制文件
把Pod上的/etc/fstab復制到本地的/tmp目錄:
# kubectl cp nginx-6ddbbc47fb-sfdcv:/etc/fstab /tmp
11.資源對象的標簽設置
為default namespace設置testing=true標簽:
# kubectl label namespaces default testing=true
12.檢查可用的API資源類型列表
該命令經常用於檢查特定類型的資源是否已經定義,列出所有資源對象類型:
# kubectl api-resources
13.使用命令行插件
為了擴展kubectl的功能,Kubernetes從1.8版本開始引入插件機制,在1.14版本時達到穩定版。
用戶自定義插件的可執行文件名需要以“kubectl-”開頭,復制到$PATH中的某個目錄(如/usr/local/bin),然后就可以通過kubectl <plugin-name>運行自定義插件了。
例如,實現一個名為hello的插件,其功能為在屏幕上輸出字符串“hello world”:
新建名為kubectl-hello的可執行腳本文件,其內容為
echo "hello world"
復制kubectl-hello文件到/usr/local/bin/目錄下,就完成了安裝插件的工作。
然后在kubectl命令后帶上插件名稱就能使用這個插件了:
# kubectl hello
使用kubectl plugin list命令可以查看當前系統中已安裝的插件列表:
# kubectl plugin list
更完整的插件開發示例可以從https://github.com/kubernetes/sample-cli-plugin找到。