前言
今天的分享主要有以下幾個目標:
- 瞭解什麼是 Kubernetes, 架構組成及核心概念
- 可以通過 kubeadm 獨立搭建完整的集羣
- 嘗試使用 kubectl 命令操作集羣
- 學習使用 YAML 編排簡單任務
Docker 回顧
- 什麼是 Docker?
- 打包代碼及其所有依賴項的軟件的標準單元, 本質上是宿主機上的一個進程;
- 通過 namespace 實現了資源隔離, 通過 cgroups 實現了資源限制, 通過 copy-on-write 機制實現了高效的文件操作
- 與虛擬機相比, Docker 啓動速度更快, 性能接近原生 (虛擬機損失 5% 左右), 資源使用更少
- 思考:
- 什麼是 Kubernetes
- 爲什麼要用 Kubernetes
- Kubernetes 架構組成
- Kubernetes 基本概念
Kubernetes
- Kubernetes 是 Google 在 2014 年開源的一個容器集羣管理系統, 簡稱 K8S.
- Kubernetes 用於容器化應用程序的部署, 擴展和管理, 目標是讓部署容器化應用簡單高效.
技術架構及核心概念
技術架構
Master
- kube-apiserver
Kubernetes API, 集羣的統一入口, 通過 api server 控制着這些資源的訪問權限,通過使用暴露給外部用戶REST API接口執行對Kubernetes資源的CRUD操作, 處理後再提交給 Etcd 存儲.
- kube-controller-manager
處理集羣中常規後臺任務, 一個資源對應一個控制器, 而ControllerManager就是負責管理這些控制器的.
- kube-scheduler
根據調度算法爲新創建的Pod選擇一個Node節點, 可以任意部署,可以部署在同一個節點上,也可以部署在不同的節點上.
- etcd
分佈式鍵值存儲系統.用於保存集羣狀態數據, 比如Pod、Service等對象信息.
Worker
- kubelet
kubelet是Master在Node節點上的Agent, 管理本機運行容器的生命週期, 比如創建容器、Pod掛載數據卷、下載secret、獲取容器和節點狀態等工作.kubelet將每個Pod轉換成一組容器.
- kube-proxy
在Node節點上實現Pod網絡代理, 維護網絡規則和四層負載均衡工作. 主要作用就是負責 service 的實.
- docker
容器引擎, 運行容器.
核心概念
Pod
- 最小部署單元
- 一組容器的集合
- 一個Pod中的容器共享網絡命名空間
- Pod是短暫的
Controllers
- Deployment : 無狀態應用部署
- StatefulSet: 有狀態應用部署
- DaemonSet : 確保所有 Node 運行相同的 Pod
- Job : 一次性任務
- Cronjob : 定時任務
控制器是更高級層次對象, 用於部署和管理 Pod.
Service
- 防止 Pod 失聯
- 定義一組 Pod 的訪問策略
Label
- 標籤, 附加到某個資源上, 用於關聯對象、查詢和篩選
Namespaces
- 命名空間, 將對象邏輯上隔離
基礎實踐
部署方式
官方提供三種部署方式:
- minikube
Minikube是一個工具,可以在本地快速運行一個單點的Kubernetes,僅用於嘗試Kubernetes或日常開發的用戶使用。
部署地址:https://kubernetes.io/docs/setup/minikube
- kubeadm
Kubeadm也是一個工具,提供kubeadm init和kubeadm join,用於快速部署Kubernetes集羣。
部署地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm
- 二進制
推薦,從官方下載發行版的二進制包,手動部署每個組件,組成Kubernetes集羣。
下載地址:https://github.com/kubernetes/kubernetes/releases
部署集羣
kubeadm是官方社區推出的一個用於快速部署kubernetes集羣的工具.
這個工具能通過兩條指令完成一個kubernetes集羣的部署:
# 創建一個 Master 節點
$ kubeadm init
# 將一個 Node 節點加入到當前集羣中
$ kubeadm join <Master節點的IP和端口 >
安裝要求
在開始之前, 部署Kubernetes集羣機器需要滿足以下幾個條件:
- 一臺或多臺機器, 操作系統 CentOS7.x-86_x64
- 硬件配置:>=2GB mem, >=2 core, >=30GB disk
- 集羣中所有機器之間網絡互通
- 可以訪問外網, 需要拉取鏡像
- 禁止swap分區
準備環境
角色 | IP |
---|---|
k8s-master | 192.168.0.10 |
k8s-node1 | 192.168.0.11 |
k8s-node2 | 192.168.0.12 |
#關閉防火牆
$ systemctl stop firewalld
$ systemctl disable firewalld
#關閉selinux
$ sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
$ setenforce 0 # 臨時
#關閉swap
$ swapoff -a # 臨時
$ vim /etc/fstab # 永久
#設置主機名
$ hostnamectl set-hostname <hostname>
#在master添加hosts
$ cat >> /etc/hosts << EOF
192.168.0.1 k8s-master
192.168.0.2 k8s-node1
192.168.0.3 k8s-node2
EOF
#將橋接的IPv4流量傳遞到iptables的鏈
$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system # 生效
#時間同步
$ yum install ntpdate -y
$ ntpdate -u cn.ntp.org.cn
所有節點安裝Docker/kubeadm/kubelet
Kubernetes 默認 CRI(容器運行時)爲 Docker, 因此先安裝 Docker.
1、 安裝Docker
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum install -y docker-ce-18.09.9-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
# cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
2、 添加阿里雲 YUM 軟件源
$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
3、 安裝 kubeadm, kubelet 和 kubectl
由於版本更新頻繁, 這裏指定版本號部署:
$ yum install -y kubelet-1.16.2 kubeadm-1.16.2 kubectl-1.16.2
$ systemctl enable kubelet
部署 Kubernetes Master
在192.168.0.10(Master)執行.
$ kubeadm init \
--apiserver-advertise-address=192.168.0.10 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.16.2 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
kubeadm 到底做了什麼? 稍後說明.
由於默認拉取鏡像地址k8s.gcr.io國內無法訪問, 這裏指定阿里雲鏡像倉庫地址.
使用kubectl工具:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl get nodes
安裝Pod網絡插件(CNI)
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
確保能夠訪問到quay.io這個registery.
加入Kubernetes Node
在192.168.0.11/12(Worker)執行.
向集羣添加新節點, 執行在kubeadm init輸出的kubeadm join命令:
$ kubeadm join 192.168.0.10:6443 --token i1ofj9.ujm6xpc7sx4tmt1c \
--discovery-token-ca-cert-hash sha256:7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9
默認token有效期爲24小時, 超時就需要重新創建token, 操作如下:
# Master 節點執行
$ kubeadm token create
i1ofj9.ujm6xpc7sx4tmt1c
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9
# Worker 上執行
$ kubeadm join 192.168.0.10:6443 --token i1ofj9.ujm6xpc7sx4tmt1c --discovery-token-ca-cert-hash sha256:7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9
也可以通過如下命令直接獲取
$ kubeadm token create --print-join-command
官方文檔: https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join
測試kubernetes集羣
在Kubernetes集羣中創建一個pod, 驗證是否正常運行:
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc
訪問地址:http://NodeIP:Port
部署 Dashboard
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml
默認Dashboard只能集羣內部訪問, 修改Service爲NodePort類型, 暴露到外部:
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
訪問地址:http://NodeIP:Port
創建service account並綁定默認cluster-admin管理員集羣角色:
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
使用輸出的token登錄Dashboard.
kubeadm init 到底做了些什麼
[root@Ali-irvin ~]# kubeadm init \ > --apiserver-advertise-address=192.168.0.10 \ > --image-repository registry.aliyuncs.com/google_containers \ > --kubernetes-version v1.16.2 \ > --service-cidr=10.96.0.0/12 \ > --pod-network-cidr=10.244.0.0/16 [init] Using Kubernetes version: v1.16. # 1. 環境檢查 [preflight] Running pre-flight checks [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/ # 2. 下載鏡像 [preflight] Pulling images required for setting up a Kubernetes cluster [preflight] This might take a minute or two, depending on the speed of your internet connection [preflight] You can also perform this action in beforehand using 'kubeadm config images pull' # 3. 爲 kubelet 創建配置文件並啓動 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Activating the kubelet service # 4. 爲apiserver、etcd生成https證書 [certs] Using certificateDir folder "/etc/kubernetes/pki" [certs] Generating "ca" certificate and key [certs] Generating "apiserver" certificate and key [certs] apiserver serving cert is signed for DNS names [ali-irvin kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.10] [certs] Generating "apiserver-kubelet-client" certificate and key [certs] Generating "front-proxy-ca" certificate and key [certs] Generating "front-proxy-client" certificate and key [certs] Generating "etcd/ca" certificate and key [certs] Generating "etcd/server" certificate and key [certs] etcd/server serving cert is signed for DNS names [ali-irvin localhost] and IPs [192.168.0.10 127.0.0.1 ::1] [certs] Generating "etcd/peer" certificate and key [certs] etcd/peer serving cert is signed for DNS names [ali-irvin localhost] and IPs [192.168.0.10 127.0.0.1 ::1] [certs] Generating "etcd/healthcheck-client" certificate and key [certs] Generating "apiserver-etcd-client" certificate and key [certs] Generating "sa" key and public key # 5. 生成連接apiserver的kubeconfig文件 [kubeconfig] Using kubeconfig folder "/etc/kubernetes" [kubeconfig] Writing "admin.conf" kubeconfig file [kubeconfig] Writing "kubelet.conf" kubeconfig file [kubeconfig] Writing "controller-manager.conf" kubeconfig file [kubeconfig] Writing "scheduler.conf" kubeconfig file # 6. 容器啓動 master 組件 [control-plane] Using manifest folder "/etc/kubernetes/manifests" [control-plane] Creating static Pod manifest for "kube-apiserver" [control-plane] Creating static Pod manifest for "kube-controller-manager" [control-plane] Creating static Pod manifest for "kube-scheduler" [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests" [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s [apiclient] All control plane components are healthy after 18.002987 seconds # 7. 將涉及的配置文件存儲到 configmap [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace [kubelet] Creating a ConfigMap "kubelet-config-1.16" in namespace kube-system with the configuration for the kubelets in the cluster [upload-certs] Skipping phase. Please see --upload-certs # 8. 設置 master 節點不可調度 Pod [mark-control-plane] Marking the node ali-irvin as control-plane by adding the label "node-role.kubernetes.io/master=''" [mark-control-plane] Marking the node ali-irvin as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule] # 9. 啓用 bootstrap 自動爲 kubelet 頒發證書 [bootstrap-token] Using token: i1ofj9.ujm6xpc7sx4tmt1c [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles [bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials [bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token [bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace # 10. 安裝插件:CoreDNS、kube-proxy [addons] Applied essential addon: CoreDNS [addons] Applied essential addon: kube-proxy Your Kubernetes control-plane 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/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.0.10:6443 --token i1ofj9.ujm6xpc7sx4tmt1c \ --discovery-token-ca-cert-hash sha256:7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9 [root@Ali-irvin ~]#
1、檢查系統環境是否滿足,例如swap是否關閉、配置是否滿足
2、下載所需鏡像,kubeadm config images pull
3、爲 kubelet 創建配置文件並啓動
4、爲 apiserver、etcd 生成 https 證書(/etc/kubernetes/pki/)
5、生成連接 apiserver 的 kubeconfig 文件
6、容器啓動 master 組件
7、將涉及的配置文件存儲到 configmap
8、設置 master 節點不可調度 Pod
9、啓用 bootstrap 自動爲 kubelet 頒發證書
10、安裝插件:CoreDNS、kube-proxy
常見問題
1. 證書問題
問題: 僅火狐瀏覽器可訪問 Dashboard
原因: 官方提供的字簽證書有問題(有效時間)
解決方案:
- 刪除默認的secret
- 用自簽證書創建新的secret
- 修改 dashboard.yaml 文件
2. token 失效
$ kubeadm token create --print-join-command
3. 環境清理
$ kubeadm reset
命令行操作
kubectl --help
查看幫助信息
kubectl create --help
查看 create 命令幫助信息
命令 | 描述 |
---|---|
create | 通過文件名或標準輸入創建資源 |
expose | 將一個資源公開爲一個新的Service |
run | 在集羣中運行一個特定的鏡像 |
set | 在對象上設置特定的功能 |
get | 顯示一個或多個資源 |
explain | 文檔參考資料 |
edit | 使用默認的編輯器編輯一個資源. |
delete | 通過文件名、標準輸入、資源名稱或標籤選擇器來刪除資源. |
rollout | 管理資源的發佈 |
rolling-update | 對給定的複製控制器滾動更新 |
scale | 擴容或縮容Pod數量, Deployment、ReplicaSet、RC或Job |
autoscale | 創建一個自動選擇擴容或縮容並設置Pod數量 |
certificate | 修改證書資源 |
cluster-info | 顯示集羣信息 |
top | 顯示資源(CPU/Memory/Storage)使用.需要Heapster運行 |
cordon | 標記節點不可調度 |
uncordon | 標記節點可調度 |
drain | 驅逐節點上的應用, 準備下線維護 |
taint | 修改節點taint標記 |
describe | 顯示特定資源或資源組的詳細信息 |
logs | 在一個Pod中打印一個容器日誌.如果Pod只有一個容器, 容器名稱是可選的 |
attach | 附加到一個運行的容器 |
exec | 執行命令到容器 |
port-forward | 轉發一個或多個本地端口到一個pod |
proxy | 運行一個proxy到Kubernetes API server |
cp | 拷貝文件或目錄到容器中 |
auth | 檢查授權 |
apply | 通過文件名或標準輸入對資源應用配置 |
patch | 使用補丁修改、更新資源的字段 |
replace | 通過文件名或標準輸入替換一個資源 |
convert | 不同的API版本之間轉換配置文件 |
label | 更新資源上的標籤 |
annotate | 更新資源上的註釋 |
completion | 用於實現kubectl工具自動補全 |
api-versions | 打印受支持的API版本 |
config | 修改kubeconfig文件(用於訪問API, 比如配置認證信息) |
help | 所有命令幫助 |
plugin | 運行一個命令行插件 |
version | 打印客戶端和服務版本信息 |
使用kubectl管理應用生命週期
# 創建
$ kubectl create deployment web --image=java
$ kubectl get deploy,pods
# 發佈
$ kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web
$ kubectl get service
# 升級
$ kubectl set image deployment/web nginx=nginx:1.15
$ kubectl rollout status deployment/nginx-deployment # 查看升級狀態
# 回滾
$ kubectl rollout history deployment/web # 查看發佈記錄
$ kubectl rollout undo deployment/web # 回滾最新版本
$ kubectl rollout undo deployment/web --revision=2 # 回滾指定版本
# 刪除
$ kubectl delete deploy/web
$ kubectl delete svc/web
常用選項
-f, --filename=[]: 文件名、目錄、或者URL創建資源
-o, --output='': json|yaml|name|wide 所有查看的資源都可以用
-l, --selector='': 根據標籤過濾內容,支持運算符 '=', '==','!='.(示例 -l key1=value1,key2=value2)
資源編排
編寫YAML注意事項
YAML 是一種簡潔的非標記語言.
語法格式:
- 縮進表示層級關係
- 不支持製表符“tab”縮進, 使用空格縮進
- 通常開頭縮進 2 個空格
- 字符後縮進 1 個空格, 如冒號、逗號等
- “—” 表示YAML格式, 一個文件的開始
- “#”註釋
YAML內容解析
YAML 編排文件內容大致分爲兩部分:
# 控制器相關定義
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
spec:
replicas: 2
selector:
matchLables:
app: nginx
# 被控制對象定義
template:
metadata:
lables:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort:80
控制器定義:定義控制器屬性
被控制對象:Pod 模板, 定義容器屬性
具體字段意義:
apiVersion | API版本 |
---|---|
kind | 資源類型 |
metadata | 資源元數據 |
spec | 資源規格 |
replicas | 副本數量 |
selector | 標籤選擇器 |
template | Pod模板 |
metadata | Pod元數據 |
spec | Pod規格 |
containers | 容器配置 |
**編寫 YAML **
熟能生巧, 多寫. 另外可通過如下方式快速生成, 基於實際場景修改.
-
run
命令生成部署模板kubectl create deployment nginx --image=nginx:1.14 -o yaml --dry-run> my-deploy.yaml
-
get
命令將已有部署的應用yaml導出kubectl get my-deploy/nginx -o=yaml --export > my-deploy.yaml
-
通過
explain
查看更詳細的幫助文檔獲得kubectl explain pods.spec.containers