Kubernetes 入門
(一)什麼是 Kubernetes
1、概述
Kubernetes 是Google 2014 年建立管理的,是 Google 10 多年大規模容器管理技術 Borg 的開源版本。
Kubernetes 是容器叢集管理系統,是一個開源的平臺,可以實現容器叢集的自動化部署、自動擴縮容、維護等功能。使用 Kubernetes 我們可以:
- 快速部署應用
- 快速擴充套件應用
- 無縫對接新的應用功能
- 節省資源,優化硬體資源的使用
Kubernetes 的目標是促進完善元件和工具的生態系統,以減輕應用程式在公有云或私有云中執行的負擔。
2、特點
- 可移植:支援公有云,私有云,混合雲,多重雲(多個公共雲)
- 可擴充套件:模組化,外掛化,可掛載,可組合
- 自動化:自動部署,自動重啟,自動複製,自動伸縮/擴充套件
3、從傳統到容器化部署
a、傳統的部署方式
傳統的應用部署方式是通過外掛或指令碼來安裝應用。這樣做的缺點是應用的執行、配置、管理、所有生存週期將與當前作業系統繫結,這樣做並不利於應用的升級更新/回滾等操作,當然也可以通過建立虛機的方式來實現某些功能,但是虛擬機器非常重,並不利於可移植性。
b、容器化部署的優勢
- 快速建立/部署應用:與虛擬機器相比,容器映象的建立更加容易。
- 持續開發、整合和部署:提供可靠且頻繁的容器映象構建/部署,並使用快速和簡單的回滾(由於映象不可變性)。
- 開發和執行相分離:在 build 或者 release 階段建立容器映象,使得應用和基礎設施解耦。
- 開發,測試和生產環境一致性:在本地或外網(生產環境)執行的一致性。
- 雲平臺或其他作業系統:可以在 Ubuntu、RHEL、CoreOS、on-prem、Google Container Engine 或其它任何環境中執行。
- 分散式,彈性,微服務化:應用程式分為更小的、獨立的部件,可以動態部署和管理。
- 資源隔離
- 資源利用更高效
4、為什麼需要 Kubernetes
可以在物理或虛擬機器的 Kubernetes 叢集上執行容器化應用,Kubernetes 能提供一個以“容器為中心的基礎架構”,滿足在生產環境中執行應用的一些常見需求,如:
- 多個程序協同工作
- 儲存系統掛載
- 應用健康檢查
- 應用例項的複製
- 自動伸縮/擴充套件
- 註冊與發現
- 負載均衡
- 滾動更新
- 資源監控
- 日誌訪問
- 除錯應用程式
- 提供認證和授權
(二)Kubernetes 安裝前的準備
1、概述
本次安裝採用 Ubuntu Server X64 18.04 LTS 版本安裝 kubernetes 叢集環境,叢集節點為 1 主 2 從模式,此次對虛擬機器會有些基本要求,如下:
- OS:Ubuntu Server X64 18.04 LTS(16.04 版本步驟相同,再之前則不同)
- CPU:最低要求,1 CPU 2 核
- 記憶體:最低要求,2GB
- 磁碟:最低要求,20GB
建立三臺虛擬機器,分別命名如下:
- Ubuntu Server 18.04 X64 Kubernetes Master
- Ubuntu Server 18.04 X64 Kubernetes Slave1
- Ubuntu Server 18.04 X64 Kubernetes Slave2
對虛擬機器系統的配置:
- 關閉交換空間:
sudo swapoff -a
- 避免開機啟動交換空間:註釋
/etc/fstab
中的swap
- 關閉防火牆:
ufw disable
2、使用 APT 安裝 Docker
安裝
# 更新軟體源
sudo apt-get update
# 安裝所需依賴
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# 安裝 GPG 證書
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 新增軟體源資訊
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 再次更新軟體源
sudo apt-get -y update
# 安裝 Docker CE 版
sudo apt-get -y install docker-ce
驗證
docker version
Client:
Version: 18.09.6
API version: 1.39
Go version: go1.10.8
Git commit: 481bc77
Built: Sat May 4 02:35:57 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.6
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: 481bc77
Built: Sat May 4 01:59:36 2019
OS/Arch: linux/amd64
Experimental: false
配置加速器
對於使用systemd的系統,請在/etc/docker/daemon.json
中寫入如下內容(如果檔案不存在請新建該檔案)
{
"registry-mirrors": [
"https://registry.docker-cn.com"
]
}
注意,一定要保證該檔案符合 JSON 規範,否則 Docker 將不能啟動。
驗證加速器是否配置成功:
sudo systemctl restart docker
docker info
...
# 出現如下語句即表示配置成功
Registry Mirrors:
https://registry.docker-cn.com/
...
3、修改主機名
在同一區域網中主機名不應該相同,所以我們需要做修改,下列操作步驟為修改18.04版本的 Hostname,如果是 16.04 或以下版本則直接修改/etc/hostname
裡的名稱即可
檢視當前 Hostname
# 檢視當前主機名
hostnamectl
# 顯示如下內容
Static hostname: ubuntu
Icon name: computer-vm
Chassis: vm
Machine ID: 33011e0a95094672b99a198eff07f652
Boot ID: dc856039f0d24164a9f8a50c506be96d
Virtualization: vmware
Operating System: Ubuntu 18.04.2 LTS
Kernel: Linux 4.15.0-48-generic
Architecture: x86-64
修改 Hostname
# 使用 hostnamectl 命令修改,其中 kubernetes-master 為新的主機名
hostnamectl set-hostname kubernetes-master
修改 cloud.cfg
如果cloud-init package
安裝了,需要修改cloud.cfg
檔案。該軟體包通常預設安裝用於處理 cloud
# 如果有該檔案
vi /etc/cloud/cloud.cfg
# 該配置預設為 false,修改為 true 即可
preserve_hostname: true
驗證
root@kubernetes-master:~# hostnamectl Static hostname: kubernetes-master Icon name: computer-vm Chassis: vm Machine ID: 33011e0a95094672b99a198eff07f652 Boot ID: 8c0fd75d08c644abaad3df565e6e4cbd Virtualization: vmware Operating System: Ubuntu 18.04.2 LTS Kernel: Linux 4.15.0-48-generic Architecture: x86-64
(三)安裝 kubeadm
1、概述
kubeadm 是 kubernetes 的叢集安裝工具,能夠快速安裝 kubernetes 叢集。
2、配置軟體源
# 安裝系統工具
apt-get update && apt-get install -y apt-transport-https
# 安裝 GPG 證書
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
# 寫入軟體源;注意:我們用系統代號為 bionic,但目前阿里雲不支援,所以沿用 16.04 的 xenial
cat << EOF >/etc/apt/sources.list.d/kubernetes.list
> deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
> EOF
3、安裝 kubeadm,kubelet,kubectl
# 安裝
apt-get update
apt-get install -y kubelet kubeadm kubectl
指定版本:
apt-get install -y kubelet=1.14.1-00 kubeadm=1.14.1-00 kubectl=1.14.1-00
# 安裝過程如下,注意 kubeadm 的版本號
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
conntrack cri-tools kubernetes-cni socat
The following NEW packages will be installed:
conntrack cri-tools kubeadm kubectl kubelet kubernetes-cni socat
0 upgraded, 7 newly installed, 0 to remove and 96 not upgraded.
Need to get 50.6 MB of archives.
After this operation, 290 MB of additional disk space will be used.
Get:1 http://mirrors.aliyun.com/ubuntu bionic/main amd64 conntrack amd64 1:1.4.4+snapshot20161117-6ubuntu2 [30.6 kB]
Get:2 http://mirrors.aliyun.com/ubuntu bionic/main amd64 socat amd64 1.7.3.2-2ubuntu2 [342 kB]
Get:3 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 cri-tools amd64 1.12.0-00 [5,343 kB]
Get:4 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 kubernetes-cni amd64 0.7.5-00 [6,473 kB]
Get:5 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 kubelet amd64 1.14.1-00 [21.5 MB]
Get:6 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 kubectl amd64 1.14.1-00 [8,806 kB]
Get:7 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 kubeadm amd64 1.14.1-00 [8,150 kB]
Fetched 50.6 MB in 5s (9,912 kB/s)
Selecting previously unselected package conntrack.
(Reading database ... 67205 files and directories currently installed.)
Preparing to unpack .../0-conntrack_1%3a1.4.4+snapshot20161117-6ubuntu2_amd64.deb ...
Unpacking conntrack (1:1.4.4+snapshot20161117-6ubuntu2) ...
Selecting previously unselected package cri-tools.
Preparing to unpack .../1-cri-tools_1.12.0-00_amd64.deb ...
Unpacking cri-tools (1.12.0-00) ...
Selecting previously unselected package kubernetes-cni.
Preparing to unpack .../2-kubernetes-cni_0.7.5-00_amd64.deb ...
Unpacking kubernetes-cni (0.7.5-00) ...
Selecting previously unselected package socat.
Preparing to unpack .../3-socat_1.7.3.2-2ubuntu2_amd64.deb ...
Unpacking socat (1.7.3.2-2ubuntu2) ...
Selecting previously unselected package kubelet.
Preparing to unpack .../4-kubelet_1.14.1-00_amd64.deb ...
Unpacking kubelet (1.14.1-00) ...
Selecting previously unselected package kubectl.
Preparing to unpack .../5-kubectl_1.14.1-00_amd64.deb ...
Unpacking kubectl (1.14.1-00) ...
Selecting previously unselected package kubeadm.
Preparing to unpack .../6-kubeadm_1.14.1-00_amd64.deb ...
Unpacking kubeadm (1.14.1-00) ...
Setting up conntrack (1:1.4.4+snapshot20161117-6ubuntu2) ...
Setting up kubernetes-cni (0.7.5-00) ...
Setting up cri-tools (1.12.0-00) ...
Setting up socat (1.7.3.2-2ubuntu2) ...
Setting up kubelet (1.14.1-00) ...
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /lib/systemd/system/kubelet.service.
Setting up kubectl (1.14.1-00) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
# 注意這裡的版本號,我們使用的是 kubernetes v1.14.1
Setting up kubeadm (1.14.1-00) ...
# 設定 kubelet 自啟動,並啟動 kubelet
systemctl enable kubelet && systemctl start kubelet
- kubeadm:用於初始化 Kubernetes 叢集
- kubectl:Kubernetes 的命令列工具,主要作用是部署和管理應用,檢視各種資源,建立,刪除和更新元件
- kubelet:主要負責啟動 Pod 和容器
(四)配置 kubeadm
1、概述
安裝 kubernetes 主要是安裝它的各個映象,而 kubeadm 已經為我們整合好了執行 kubernetes 所需的基本映象。但由於國內的網路原因,在搭建環境時,無法拉取到這些映象。此時我們只需要修改為阿里雲提供的映象服務即可解決該問題。
2、建立並修改配置
# 匯出配置檔案
kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml
# 修改配置為如下內容
apiVersion: kubeadm.k8s.io/v1beta1
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
# 修改為主節點 IP
advertiseAddress: 192.168.141.130
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: kubernetes-master
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: ""
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
# 國內不能訪問 Google,修改為阿里雲
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
# 修改版本號
kubernetesVersion: v1.14.1
networking:
dnsDomain: cluster.local
# 配置成 Calico 的預設網段
podSubnet: "192.168.0.0/16"
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
# 開啟 IPVS 模式
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
3、檢視和拉取映象
# 檢視所需映象列表
kubeadm config images list --config kubeadm.yml
# 拉取映象
kubeadm config images pull --config kubeadm.yml
(五)使用 kubeadm 搭建 kubernetes 叢集
1、安裝 kubernetes 主節點
執行以下命令初始化主節點,該命令指定了初始化時需要使用的配置檔案,其中新增--experimental-upload-certs
引數可以在後續執行加入節點時自動分發證書檔案。追加的tee kubeadm-init.log
用以輸出日誌。
Flag --experimental-upload-certs has been deprecated, use --upload-certs instead
則將–experimental-upload-certs 替換為 --upload-certs
kubeadm init --config=kubeadm.yml --upload-certs | tee kubeadm-init.log
kubeadm init --config=kubeadm.yml --experimental-upload-certs | tee kubeadm-init.log
# 安裝成功則會有如下輸出
[init] Using Kubernetes version: v1.14.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/
[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'
[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
[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 [kubernetes-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.141.130]
[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/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [kubernetes-master localhost] and IPs [192.168.141.130 127.0.0.1 ::1]
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [kubernetes-master localhost] and IPs [192.168.141.130 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
[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
[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 20.003326 seconds
[upload-config] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.14" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Storing the certificates in ConfigMap "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
2cd5b86c4905c54d68cc7dfecc2bf87195e9d5d90b4fff9832d9b22fc5e73f96
[mark-control-plane] Marking the node kubernetes-master as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node kubernetes-master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: abcdef.0123456789abcdef
[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
[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.141.130:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:cab7c86212535adde6b8d1c7415e81847715cfc8629bb1d270b601744d662515
注意:如果安裝 kubernetes 版本和下載的映象版本不統一則會出現
timed out waiting for the condition
錯誤。中途失敗或是想修改配置可以使用kubeadm reset
命令重置配置,再做初始化操作即可。
2、配置 kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 非 ROOT 使用者執行
chown $(id -u):$(id -g) $HOME/.kube/config
3、驗證是否成功
kubectl get node
# 能夠打印出節點資訊即表示成功
NAME STATUS ROLES AGE VERSION
kubernetes-master NotReady master 8m40s v1.14.1
至此主節點配置完成
4、kubeadm init 的執行過程
- init:指定版本進行初始化操作
- preflight:初始化前的檢查和下載所需要的 Docker 映象檔案
- kubelet-start:生成 kubelet 的配置檔案
var/lib/kubelet/config.yaml
,沒有這個檔案 kubelet 無法啟動,所以初始化之前的 kubelet 實際上啟動不會成功 - certificates:生成 Kubernetes 使用的證書,存放在
/etc/kubernetes/pki
目錄中 - kubeconfig:生成 KubeConfig 檔案,存放在
/etc/kubernetes
目錄中,元件之間通訊需要使用對應檔案 - control-plane:使用
/etc/kubernetes/manifest
目錄下的 YAML 檔案,安裝 Master 元件 - etcd:使用
/etc/kubernetes/manifest/etcd.yaml
安裝 Etcd 服務 - wait-control-plane:等待 control-plan 部署的 Master 元件啟動
- apiclient:檢查 Master 元件服務狀態。
- uploadconfig:更新配置
- kubelet:使用 configMap 配置 kubelet
- patchnode:更新 CNI 資訊到 Node 上,通過註釋的方式記錄
- mark-control-plane:為當前節點打標籤,打了角色 Master,和不可排程標籤,這樣預設就不會使用 Master 節點來執行 Pod
- bootstrap-token:生成 token 記錄下來,後邊使用
kubeadm join
往叢集中新增節點時會用到 - addons:安裝附加元件 CoreDNS 和 kube-proxy
(六)使用 kubeadm 配置 slave 節點
1、概述
將 slave 節點加入到叢集中很簡單,只需要在 slave 伺服器上安裝 kubeadm,kubectl,kubelet 三個工具,然後使用kubeadm join
命令加入即可。準備工作如下:
- 修改主機名
- 配置軟體源
- 安裝三個工具
2、將 slave 加入到叢集
kubeadm join 192.168.141.130:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:cab7c86212535adde6b8d1c7415e81847715cfc8629bb1d270b601744d662515
# 安裝成功將看到如下資訊
[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/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.14" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Activating the kubelet service
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
說明:
- token
- 可以通過安裝 master 時的日誌檢視 token 資訊
- 可以通過
kubeadm token list
命令打印出 token 資訊 - 如果 token 過期,可以使用
kubeadm token create
命令建立新的 token
- discovery-token-ca-cert-hash
- 可以通過安裝 master 時的日誌檢視 sha256 資訊
- 可以通過
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
命令檢視 sha256 資訊
3、驗證是否成功
回到 master 伺服器
kubectl get nodes
# 可以看到 slave 成功加入 master
NAME STATUS ROLES AGE VERSION
kubernetes-master NotReady master 9h v1.14.1
kubernetes-slave1 NotReady <none> 22s v1.14.1
如果 slave 節點加入 master 時配置有問題可以在 slave 節點上使用
kubeadm reset
重置配置再使用kubeadm join
命令重新加入即可。希望在 master 節點刪除 node ,可以使用kubeadm delete nodes <NAME>
刪除。
4、檢視 pod 狀態
kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-8686dcc4fd-gwrmb 0/1 Pending 0 9h <none> <none> <none> <none>
coredns-8686dcc4fd-j6gfk 0/1 Pending 0 9h <none> <none> <none> <none>
etcd-kubernetes-master 1/1 Running 1 9h 192.168.141.130 kubernetes-master <none> <none>
kube-apiserver-kubernetes-master 1/1 Running 1 9h 192.168.141.130 kubernetes-master <none> <none>
kube-controller-manager-kubernetes-master 1/1 Running 1 9h 192.168.141.130 kubernetes-master <none> <none>
kube-proxy-496dr 1/1 Running 0 17m 192.168.141.131 kubernetes-slave1 <none> <none>
kube-proxy-rsnb6 1/1 Running 1 9h 192.168.141.130 kubernetes-master <none> <none>
kube-scheduler-kubernetes-master 1/1 Running 1 9h 192.168.141.130 kubernetes-master <none> <none>
由此可以看出 coredns 尚未執行,此時我們還需要安裝網路外掛。
(七)配置網路
1、概述
容器網路是容器選擇連線到其他容器、主機和外部網路的機制。容器的 runtime 提供了各種網路模式,每種模式都會產生不同的體驗。例如,Docker 預設情況下可以為容器配置以下網路:
- none:將容器新增到一個容器專門的網路堆疊中,沒有對外連線。
- host:將容器新增到主機的網路堆疊中,沒有隔離。
- default bridge:預設網路模式。每個容器可以通過 IP 地址相互連線。
- 自定義網橋:使用者定義的網橋,具有更多的靈活性、隔離性和其他便利功能。
2、什麼是 CNI
CNI(Container Network Interface) 是一個標準的,通用的介面。在容器平臺,Docker,Kubernetes,Mesos 容器網路解決方案 flannel,calico,weave。只要提供一個標準的介面,就能為同樣滿足該協議的所有容器平臺提供網路功能,而 CNI 正是這樣的一個標準介面協議。
3、Kubernetes 中的 CNI 外掛
CNI 的初衷是建立一個框架,用於在配置或銷燬容器時動態配置適當的網路配置和資源。外掛負責為介面配置和管理 IP 地址,並且通常提供與 IP 管理、每個容器的 IP 分配、以及多主機連線相關的功能。容器執行時會呼叫網路外掛,從而在容器啟動時分配 IP 地址並配置網路,並在刪除容器時再次呼叫它以清理這些資源。
執行時或協調器決定了容器應該加入哪個網路以及它需要呼叫哪個外掛。然後,外掛會將介面新增到容器網路名稱空間中,作為一個 veth 對的一側。接著,它會在主機上進行更改,包括將 veth 的其他部分連線到網橋。再之後,它會通過呼叫單獨的 IPAM(IP地址管理)外掛來分配 IP 地址並設定路由。
在 Kubernetes 中,kubelet 可以在適當的時間呼叫它找到的外掛,為通過 kubelet 啟動的 pod進行自動的網路配置。
Kubernetes 中可選的 CNI 外掛如下:
- Flannel
- Calico
- Canal
- Weave
4、什麼是 Calico
Calico 為容器和虛擬機器提供了安全的網路連線解決方案,並經過了大規模生產驗證(在公有云和跨數千個叢集節點中),可與 Kubernetes,OpenShift,Docker,Mesos,DC / OS 和 OpenStack 整合。
Calico 還提供網路安全規則的動態實施。使用 Calico 的簡單策略語言,您可以實現對容器,虛擬機器工作負載和裸機主機端點之間通訊的細粒度控制。
5、安裝網路外掛 Calico
注意:截止到文章發表日期 2019 年 05 月 11 日,Calico 官方版本為 3.7
參考官方文件安裝:https://docs.projectcalico.org/v3.7/getting-started/kubernetes/
# 在 Master 節點操作即可
kubectl apply -f https://docs.projectcalico.org/v3.7/manifests/calico.yaml
# 安裝時顯示如下輸出
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.extensions/calico-node created
serviceaccount/calico-node created
deployment.extensions/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
確認安裝是否成功
watch kubectl get pods --all-namespaces
# 需要等待所有狀態為 Running,注意時間可能較久,3 - 5 分鐘的樣子
Every 2.0s: kubectl get pods --all-namespaces kubernetes-master: Fri May 10 18:16:51 2019
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-8646dd497f-g2lln 1/1 Running 0 50m
kube-system calico-node-8jrtp 1/1 Running 0 50m
kube-system coredns-8686dcc4fd-mhwfn 1/1 Running 0 51m
kube-system coredns-8686dcc4fd-xsxwk 1/1 Running 0 51m
kube-system etcd-kubernetes-master 1/1 Running 0 50m
kube-system kube-apiserver-kubernetes-master 1/1 Running 0 51m
kube-system kube-controller-manager-kubernetes-master 1/1 Running 0 51m
kube-system kube-proxy-p8mdw 1/1 Running 0 51m
kube-system kube-scheduler-kubernetes-master 1/1 Running 0 51m
至此基本環境已部署完畢。
5、解決 ImagePullBackOff
在使用watch kubectl get pods --all-namespaces
命令觀察 Pods 狀態時如果出現ImagePullBackOff
無法 Running 的情況,請嘗試使用如下步驟處理:
- Master 中刪除 Nodes:
kubeadm delete nodes <NAME>
- Slave 中重置配置:
kubeadm reset
- Slave 重啟計算機:
reboot
- Slave 重新加入叢集:
kubeadm join
6、附:配置固定 IP 和 DNS
當關機後再啟動虛擬機器有時 IP 地址會自動更換,導致之前的配置不可用;配置完 Kubernetes 網路後虛擬機器還會出現無法聯網的情況,後經研究發現是 DNS 會被自動重寫所致,Ubuntu Server 18.04 LTS 版本的 IP 和 DNS 配置也與之前的版本配置大相徑庭,故在此說明下如何修改 IP 和 DNS
a、修改固定 IP
編輯vi /etc/netplan/50-cloud-init.yaml
配置檔案,注意這裡的配置檔名未必和你機器上的相同,請根據實際情況修改。修改內容如下:
network:
ethernets:
ens33:
addresses: [192.168.141.134/24]
gateway4: 192.168.141.2
nameservers:
addresses: [192.168.141.2]
version: 2
使配置生效netplan apply
b、修改 DNS
方法一
- 停止
systemd-resolved
服務:systemctl stop systemd-resolved
- 修改 DNS:
vi /etc/resolv.conf
,將nameserver
修改為如114.114.114.114
可以正常使用的 DNS 地址
方法二
vi /etc/systemd/resolved.conf
把 DNS 取消註釋,新增 DNS,儲存退出,重啟即可
(八)第一個 Kubernetes 容器
1、檢查元件執行狀態
kubectl get cs
# 輸出如下
NAME STATUS MESSAGE ERROR
# 排程服務,主要作用是將 POD 排程到 Node
scheduler Healthy ok
# 自動化修復服務,主要作用是 Node 宕機後自動修復 Node 回到正常的工作狀態
controller-manager Healthy ok
# 服務註冊與發現
etcd-0 Healthy {"health":"true"}
2、檢查 Master 狀態
kubectl cluster-info
# 輸出如下
# 主節點狀態
Kubernetes master is running at https://192.168.141.130:6443
# DNS 狀態
KubeDNS is running at https://192.168.141.130:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
3、檢查 Nodes 狀態
kubectl get nodes
# 輸出如下,STATUS 為 Ready 即為正常狀態
NAME STATUS ROLES AGE VERSION
kubernetes-master Ready master 44h v1.14.1
kubernetes-slave1 Ready <none> 3h38m v1.14.1
kubernetes-slave2 Ready <none> 3h37m v1.14.1
4、執行第一個容器例項
# 使用 kubectl 命令建立兩個監聽 80 埠的 Nginx Pod(Kubernetes 執行容器的最小單元)
kubectl run nginx --image=nginx --replicas=2 --port=80
# 輸出如下
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created
5、檢視全部 Pods 的狀態
kubectl get pods
# 輸出如下,需要等待一小段實踐,STATUS 為 Running 即為執行成功
NAME READY STATUS RESTARTS AGE
nginx-755464dd6c-qnmwp 1/1 Running 0 90m
nginx-755464dd6c-shqrp 1/1 Running 0 90m
6、檢視已部署的服務
kubectl get deployment
# 輸出如下
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 2/2 2 2 91m
7、對映服務,讓使用者可以訪問
kubectl expose deployment nginx --port=80 --type=LoadBalancer
# 輸出如下
service/nginx exposed
8、檢視已釋出的服務
kubectl get services
# 輸出如下
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 44h
# 由此可見,Nginx 服務已成功釋出並將 80 埠對映為 31738
nginx LoadBalancer 10.108.121.244 <pending> 80:31738/TCP 88m
9、檢視服務詳情
kubectl describe service nginx
# 輸出如下
Name: nginx
Namespace: default
Labels: run=nginx
Annotations: <none>
Selector: run=nginx
Type: LoadBalancer
IP: 10.108.121.244
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 31738/TCP
Endpoints: 192.168.17.5:80,192.168.8.134:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
10、驗證是否成功
通過瀏覽器訪問 Master 伺服器
http://192.168.141.130:31738/
此時 Kubernetes 會以負載均衡的方式訪問部署的 Nginx 服務,能夠正常看到 Nginx 的歡迎頁即表示成功。容器實際部署在其它 Node 節點上,通過訪問 Node 節點的 IP:Port 也是可以的。
11、停止服務
kubectl delete deployment nginx
# 輸出如下
deployment.extensions "nginx" deleted
kubectl delete service nginx # 輸出如下 service "nginx" deleted
(九)概念總結
1、什麼是 Kubernetes
Kubernetes 是一個開源的 Docker 容器編排系統,它可以排程計算叢集的節點,動態管理上面的作業,保證它們按使用者期望的狀態執行。通過使用「labels」和「pods」的概念,Kubernetes 將應用按邏輯單元進行分組,方便管理和服務發現。
- pods:是一組緊密關聯的容器集合,它們共享 IPC(程序間通訊)、Network(網路) 和 UTS namespace(UTS 名稱空間是 Linux 名稱空間的一個子系統,主要作用是完成對容器 Hostname 和 Domain 的隔離,同時儲存核心名稱、版本、以及底層體系結構型別等資訊),是 Kubernetes 排程的基本單位。
- labels:鍵值對(key/value)標籤,可以被關聯到如 Pod 這樣的物件上,主要作用是給使用者一個直觀的感受,比如這個 Pod 是用來放置資料庫的
- GUI:使用者圖形介面,可以是 Web 使用者介面,比如使用
kubernetes-dashboard
元件,使用者可以通過 Dashboard 在 Kubernetes 叢集中部署容器化的應用,可以檢視叢集中應用的執行情況,同時也能夠基於 Dashboard 建立或修改部署、任務、服務等 Kubernetes 的資源。通過部署嚮導,使用者能夠對部署進行擴縮容,進行滾動更新、重啟 Pod 和部署新應用。當然,通過 Dashboard 也能夠檢視 Kubernetes 資源的狀態 - kubectl:用於管理 Kubernetes 叢集的命令列工具
- kube-apiserver:提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API 註冊和發現等機制
- Kubernetes Master:Kubernetes 叢集主節點,主要由
kube-apiserver
、kube-scheduler
、kube-controller-manager
、etcd
四個模組組成 - Kubernetes Node:Kubernetes 叢集子節點,主要由
kubelet
、kube-proxy
、runtime
三個模組組成 - Image Registry:映象倉庫,比如:Ducker HUB 或 Docker 私服
2、Kubernetes Master
- kube-apiserver:提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API 註冊和發現等機制
- kube-scheduler:負責資源的排程,按照預定的排程策略將 Pod 排程到相應的機器上
- kube-controller-manager:負責維護叢集的狀態,比如故障檢測、自動擴充套件、滾動更新等
- etcd:CoreOS 基於 Raft 開發的分散式 key-value 儲存,可用於服務發現、共享配置以及一致性保障(如資料庫選主、分散式鎖等)
3、Kubernetes Node
- runtime:負責映象管理以及 Pod 和容器的真正執行(CRI,Container Runtime Interface),預設的容器執行時為 Docker,還支援 RKT 容器
- kubelet:負責維持容器的生命週期,同時也負責 Volume(CVI,Container Volume Interface)和網路(CNI,Container Network Interface)的管理
- kube-proxy:負責為 Service 提供 cluster 內部的服務發現和負載均衡
4、Kubernetes 架構
轉自:有夢想的鹹魚