雲原生時代之Kubernetes容器編排初步探索及部署、使用實戰-v1.22

概述

**本人部落格網站 **IT小神 www.itxiaoshen.com

Kubernetes官網地址 //kubernetes.io

Kubernetes GitHub源碼地址 //github.com/kubernetes/kubernetes

Kubernetes,也稱為K8s,生產級別的容器編排系統,是一個用於自動化部署、擴展和管理容器化應用程式的開源系統。

  • Kubernetes,是一個go語言開發(docker也是go語言開發,可見go語言的厲害和趨勢,其兼具 Python 等動態語言的開發速度和 C/C++ 等編譯型語言的性能與安全性」,部署簡單、並發性好、語言設計良好、執行性能高,後續我們專題學習它)用於跨多個主機管理容器化應用程式的開放源程式碼系統。它為應用程式的部署、維護和擴展提供了基本機制。
  • Kubernetes的發展歷史,從公有雲Iaas、Paas、Saas的雲計算時代開始,到Docker Swarm用於容器化集群和Apache Mesos為分散式資源管理框架,最終成為容器化編排主流引領者

特性

  • 自動化上線和回滾

    • Kubernetes 會分步驟地將針對應用或其配置的更改上線,同時監視應用程式運行狀況以確保你不會同時終止所有實例。如果出現問題,Kubernetes 會為你回滾所作更改。你應該充分利用不斷成長的部署方案生態系統。
  • 服務發現與負載均衡

    • 無需修改你的應用程式即可使用陌生的服務發現機制。Kubernetes 為容器提供了自己的 IP 地址和一個 DNS 名稱,並且可以在它們之間實現負載均衡。
  • 存儲編排

    • 自動掛載所選存儲系統,包括本地存儲、諸如 GCPAWS 之類公有雲提供商所提供的存儲或者諸如 NFS、iSCSI、Gluster、Ceph、Cinder 或 Flocker 這類網路存儲系統。
  • 密鑰和配置管理

    • 部署和更新 Secrets 和應用程式的配置而不必重新構建容器鏡像,且 不必將軟體堆棧配置中的秘密資訊暴露出來。
  • 自動裝箱

    • 根據資源需求和其他約束自動放置容器,同時避免影響可用性。將關鍵性工作負載和儘力而為性質的服務工作負載進行混合放置,以提高資源利用率並節省更多資源。
  • 批量執行

    • 除了服務之外,Kubernetes 還可以管理你的批處理和 CI 工作負載,在期望時替換掉失效的容器。
  • IPv4/IPv6 雙協議棧

    • 為 Pod 和 Service 分配 IPv4 和 IPv6 地址
  • 水平擴縮

    • 使用一個簡單的命令、一個 UI 或基於 CPU 使用情況自動對應用程式進行擴縮。
  • 自我修復

    • 重新啟動失敗的容器,在節點死亡時替換並重新調度容器,殺死不響應用戶定義的健康檢查的容器,並且在它們準備好服務之前不會將它們公布給客戶端。
  • 為擴展性設計

    • 無需更改上游源碼即可擴展你的 Kubernetes 集群

kubernetes使用

文檔

kubernetes中文文檔地址 //kubernetes.io/zh/docs/home

目前最新版本為 v1.22 ,對於自己管理的集群,官方支援的用於部署 Kubernetes 的工具是 kubeadm

演進過程:傳統部署時代虛擬化部署時代容器部署時代

  • 傳統部署時代:在物理伺服器上運行應用程式
  • 虛擬化部署時代:虛擬化技術允許你在單個物理伺服器的 CPU 上運行多個虛擬機
  • 容器部署時代:與 VM 類似,可以在應用程式之間共享作業系統,容器被認為是輕量級的,具有自己的文件系統、CPU、記憶體、進程空間

image-20210908182227323

概念

Kubernetes 組件

image-20210908182528070

image-20210910183024315

image-20210913134156961

  • 控制平面組件(Control Plane Components)

    • kube-apiserver:提供了 Kubernetes API的統一入口,是 Kubernetes 控制面的前端,提供 HTTP API,以供用戶、集群中的不同部分和集群外部組件相互通訊,可以查詢和操縱 Kubernetes API 中對象(例如:Pod、Namespace、ConfigMap 和 Event)的狀態,大部分操作都可以通過kubectl命令行介面或 類似kubeadm這類命令行工具來執行, 這些工具在背後也是調用 API,也可以使用 REST 調用來訪問這些 API或者使用客戶端庫

    image-20210914094948096

    • etcd:兼具一致性和高可用性的分散式鍵值資料庫,用於保存 Kubernetes 所有集群和狀態包括Pod、Deployment、Service等
    • kube-scheduler:負責監視新創建的、未指定運行節點和pod,計算和選擇 Pod 在哪些節點上運行,包括節點控制器、任務控制器、端點控制器等
    • kube-controller-manager:用於集群監控、故障轉移等,執行集群級別的功能,如複製組件、追蹤工作結點狀態、處理結點失敗等
  • 可選組件

    • kube-dns:負責整個集群內部dns解析服務,屬於非必要組件,可實現所有pod通過名稱訪問
    • dashboard:儀錶盤,是 Kubernetes 集群的通用的、基於 Web 的用戶介面。 它使用戶可以管理集群中運行的應用程式以及集群本身並進行故障排除
    • cloud-controller-manager:嵌入特定雲的控制邏輯的控制平面組件
  • Node 組件(節點可以是一個虛擬機或者物理機器,節點組件在每個節點上運行,負責運行容器的軟體維護運行的 Pod )

    • kubelet:負責節點上運行Pod容器中,管理工作節點上的容器
    • kube-proxy:主節點代理,集群中每個節點上運行的網路代理,實現Kubernetes 的Service映射訪問
    • 容器運行時:提供 Kubernetes 運行環境實際運行容器的組件比如docker、containerd、CRI-O
  • 網路插件(兩個docker宿主機之間通訊需要具有實現CNI的插件)

    • 部署基於 Pod 網路插件的容器網路介面(CNI),讓 Pod 可以相互通訊,網路插件包括Calico、Flannel、Cilium、Weave等,官方還提供其他網路插件

image-20210914093719017

概念

Pod

Pod 是可以在 Kubernetes 中創建和管理的、最小的可部署的計算單元和調度單位,Pod可以包含是一個或者多個容器化應用、掛載和網路。而一個節點Node只要資源足夠是可以運行和管理很多很多的pod;Pod安裝在節點上,包含一組容器和卷。同一個Pod里的容器共享同一個網路命名空間,可以使用localhost互相通訊

如果Pod是短暫的,那麼怎麼才能持久化容器數據使其能夠跨重啟而存在? 是的,Kubernetes支援卷的概念,因此可以使用持久化的卷類型。

image-20210910184012016

image-20210910184625030

Replication Controller

是否手動創建Pod,如果想要創建同一個容器的多份拷貝,需要一個個分別創建出來么?可以手動創建單個Pod,但是也可以使用Replication Controller使用Pod模板創建出多份拷貝。

Replication Controller確保任意時間都有指定數量的Pod「副本」在運行。如果為某個Pod創建了Replication Controller並且指定3個副本,它會創建3個Pod,並且持續監控它們。如果某個Pod不響應,那麼Replication Controller會替換它,保持總數為3。如果之前不響應的Pod恢復了,現在就有4個Pod了,那麼Replication Controller會將其中一個終止保持總數為3。如果在運行中將副本總數改為5,Replication Controller會立刻啟動2個新Pod,保證總數為5。還可以按照這樣的方式縮小Pod,這個特性在執行滾動升級時很有用。

當創建Replication Controller時,需要指定兩個東西:

  • Pod模板:用來創建Pod副本的模板
  • Label:Replication Controller需要監控的Pod的標籤

image-20210913135200954

Deployment

deployment是pod版本管理的工具,用來區分不同版本的pod,保證pod的數量和健康;從開發者角度看,deployment也即是部署意思,對於完整的應用部署流程,除了運行程式碼(既pod)之外,需要考慮更新策略,副本數量,回滾,重啟等步驟

image-20210910184817707

Service

Service是一個邏輯的概念,是定義一系列Pod以及訪問這些Pod的策略的一層抽象。Service通過Label找到Pod組;通常用於將一組相同pod應用有一個虛擬網路IP進行管理,如果Pod是短暫的,那麼重啟時IP地址可能會改變,那麼怎麼才能從前端容器正確可靠地指向後台容器呢?這時可以使用Service,Service還可以實現其一組pod內部的服務發現和負載均衡,通過每個Node上運行的代理(kube-proxy)完成。

image-20210913121248157

部署

部署方式

部署Kubernetes集群有多種方式,包括kind、minikube、kubeadm、二進位文件、yum安裝、第三方工具、kops、kubespray、花錢購買

  • kind讓你能夠在本地電腦上運行 Kubernetes,一般用於學習使用
  • minikube與kind類似,運行一個單節點的 Kubernetes 集群,也是用於學習使用
  • kubeadm該工具能夠執行必要的動作並用一種用戶友好的方式啟動一個可用的、安全的集群。部署簡單,通過kubeadm init和kubeadm join兩個命令就可以創建集群。也比較適合學習Kubernetes運維,現在也比較穩定可用於生產環境
  • 二進位文件:下載二進位包,手動部署每個組件,比較繁瑣,但是能對Kubernetes各個組件有更清晰更深刻的認識
  • yum安裝:通過yum安裝每個組件,由於yum源有可能比較老,一般也較少使用
  • 第三方工具,比如GitHub有些大神封裝的一些工具用於部署Kubernetes集群
  • kops、kubespray
  • 花錢購買:比如阿里雲、騰訊雲共有雲k8s平台,一鍵搞定

image-20210914171753532

image-20210914172708540

image-20210915121941663

kubeadm方式部署

部署規劃

伺服器最低配置要求: 2core 、2G、 50G,由於需要部署docker,因此如果是centos則要求7以上

所有伺服器的作業系統

cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
主機名 IP
k8s-master2 192.168.50.36
k8s-node-1 192.168.50.34
k8s-node-2 192.168.50.35

網段劃分

名稱 IP網段 備註
service-cluster-ip 10.10.0.0/16 可用地址 65534
pods-ip 10.20.0.0/16 可用地址 65534
集群dns 10.10.0.2 用於集群service域名解析
k8s svc 10.10.0.1 集群 kubernetes svc 解析ip
部署步驟

下面是所有的節點均需操作

#部署docker,找出最新版本 
yum list docker-ce --showduplicates | sort -r
yum list docker-ce-cli --showduplicates | sort -r
#修改為最新的版本
yum -y install docker-ce-20.10.8 docker-ce-cli-20.10.8 containerd.io

#添加/etc/docker/daemon.json內容為
{
"registry-mirrors": ["//b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
# 重啟docker
systemctl restart docker
systemctl enable docker.service
#關閉防火牆
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>

#添加 hosts
cat >> /etc/hosts << EOF
192.168.50.34 k8s-node-1
192.168.50.35 k8s-node-2
192.168.50.36 k8s-master-2
EOF

#使橋接流量對iptables可見,將橋接的 IPv4 流量傳遞到 iptables 的鏈
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

#時間同步
yum install ntpdate -y
ntpdate time.windows.com

# 使用本地軟體包管理軟體安裝 kubectl 二進位文件
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=//mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=//mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg //mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

#安裝 kubeadm,kubelet 和 kubectl
yum install -y kubelet-1.22.1 kubeadm-1.22.1 kubectl-1.22.1
systemctl enable kubelet

image-20210916144804267

查看已安裝版本資訊

image-20210916145124707

kubeadm init --kubernetes-version=1.22.1 \
--apiserver-advertise-address=192.168.50.36 \
--ignore-preflight-errors=all \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.10.0.0/16 \
--pod-network-cidr=10.20.0.0/16

image-20210916160448137

根據上面的提示資訊繼續操作

kubectl get nodesmkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
#下面這段是後面在node節點加入k8s集群的命令
kubeadm join 192.168.50.36:6443 --token jagf90.w67s5swmocymags3 \
	--discovery-token-ca-cert-hash sha256:0afe56b1ca4354bc1148bf25c97e18412ab4f1340d3b62080d1fb1d0901d07c9 
# 如需要重新生成token重新生成加入集群命令可使用下面這個
kubeadm token create --print-join-command
#查看當前集群節點資訊,目前集群的網路還沒有打通,因此狀態為NotReady
kubectl get nodes
#查看當前節點的docker鏡像,kubeadm部署方式是以docker鏡像方式運行集群
docker images

image-20210916163524566

分別在兩台node節點192.168.50.34、192.168.50.35執行加k8s集群的命令

kubeadm join 192.168.50.36:6443 --token jagf90.w67s5swmocymags3 \
	--discovery-token-ca-cert-hash sha256:0afe56b1ca4354bc1148bf25c97e18412ab4f1340d3b62080d1fb1d0901d07c9 

image-20210916165016766

#使kubectl自動補全
source <(kubectl completion bash)
# 查詢目前三個節點的資訊如下
kubectl get nodes
kubectl get pod --all-namespaces -o wide

image-20210916165111924

接下來需要給k8s集群添加CNI網路插件,有很多方式,這裡先提供兩種

#calico網路
kubectl apply -f //docs.projectcalico.org/manifests/calico.yaml          
#或者選擇kube-flannel網路
kubectl apply -f //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#過兩分鐘後再查看節點的狀態

image-20210916170305883

image-20210917230153343

image-20210917230304013

通過查找pod的詳細資訊發現問題

#calico.yaml先下載下來
wget //docs.projectcalico.org/manifests/calico.yaml
#calico.yaml增加兩行資訊 - name: IP_AUTODETECTION_METHOD value: "interface=ens.*",interface後面根據實際,我的機器網卡是ens160所以直接填
            # Cluster type to identify the deployment type
            - name: CLUSTER_TYPE
              value: "k8s,bgp"
            - name: IP_AUTODETECTION_METHOD
              value: "interface=ens160"
            # Auto-detect the BGP IP address.
            - name: IP
              value: "autodetect"
#重新應用calico.yaml             
kubectl apply -f calico.yaml  

image-20210917230709263

我們再來解決coredns的ImagePullBackOff的問題

image-20210917230906547

#查看coredns pod的鏡像
kubectl get pods coredns-7f6cbbb7b8-d2rzk -n kube-system -o yaml | grep image    
#顯示資訊如下
    image: registry.aliyuncs.com/google_containers/coredns:v1.8.4
    imagePullPolicy: IfNotPresent
  - image: registry.aliyuncs.com/google_containers/coredns:v1.8.4
    imageID: ""
        message: Back-off pulling image "registry.aliyuncs.com/google_containers/coredns:v1.8.4"
#由於registry.aliyuncs.com/google_containers/coredns:v1.8.4官方是沒有的,官方鏡像是coredns/coredns:1.8.4
#在coredns節點上也即是k8s-node-2也即是192.168.50.35上先下載鏡像
docker pull coredns/coredns:1.8.4
#查看coredns/coredns:1.8.4鏡像的imageid,給鏡像手動打tag為registry.aliyuncs.com/google_containers/coredns:v1.8.4
docker tag 8d147537fb7d registry.aliyuncs.com/google_containers/coredns:v1.8.4

image-20210917231316719

image-20210917231440318

常見幾個問題

1.  加入集群時報錯: /etc/kubernetes/kubelet.conf already exists

原因: 上次的配置文件沒有清理乾淨,刪除即可

rm -rf /etc/kubernetes/kubelet.conf /etc/kubernetes/pki/ca.crt
2.   加入集群時報錯: [ERROR Port-10250]: Port 10250 is in use

原因:上次加入沒有成功就關閉。重置kubeadm

kubeadm reset
 3. 加入集群報錯:/proc/sys/net/ipv4/ip_forward contents are not set to 1

echo "1" >/proc/sys/net/ipv4/ip_forward

第三方方式部署

部署規劃

GitHub上搜索kubernetes二進位,選擇一個較新的進行部署

GitHub kubernetes集群部署,下載源碼文件

image-20210914182205998

伺服器最低配置要求: 2core 、2G、 50G,由於需要部署docker,因此如果是centos則要求7以上

所有伺服器的作業系統

cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)

伺服器規劃

主機名 IP
k8s-master1 192.168.50.33
k8s-node-1 192.168.50.34
k8s-node-2 192.168.50.35
nginx-ingress-slb 192.168.50.36

網段劃分

名稱 IP網段 備註
service-cluster-ip 10.10.0.0/16 可用地址 65534
pods-ip 10.20.0.0/16 可用地址 65534
集群dns 10.10.0.2 用於集群service域名解析
k8s svc 10.10.0.1 集群 kubernetes svc 解析ip

服務版本

  • Docker CE version 20.10.8
  • Kubernetes Version 1.22.1
  • Etcd Version v3.5.0

集群說明

  • 所有主機使用 CentOS Linux release 7.9.2009 (Core) 版本,並且內核都升到5.x版本。
  • kube-proxy 使用 ipvs 模式(預留iptables模式)
  • Calico 使用 IPIP 模式
  • 集群域使用默認 svc.cluster.local
  • 10.10.0.1 為集群 kubernetes svc 解析ip
  • haproxy設置TCP監聽nginx-ingress的svc埠,實現ingress高可用
  • nginx-ingress後端獲取客戶端真實IP
部署步驟
  • 初始化
    • 關閉 firewalld
    • 關閉 swap
    • 關閉 Selinux
    • 修改內核參數
    • 預先設置 PATH
    • 設置hostname
    • 判斷內核並升級
    • 安裝docker
  • 證書生成
    • 準備cfssl證書生成工具
    • 自簽TLS證書,metrics-server 證書
  • 部署Etcd集群
    • 從Github下載Etcd二進位文件和k8s相關組件,解壓k8s二進位包
    • 拷貝master上的ssl證書到node
    • 設置kubeconfig
    • 依次啟動etcd
    • 健康檢查
  • 部署Master Node
    • 部署kube-apiserver
    • 部署kube-controller-manager
    • 部署kube-scheduler
    • 配置kubelet證書自動續期和創建Node授權用戶
    • 批准kubelet證書申請並加入集群
  • 部署Worker Node
    • 創建工作目錄並拷貝二進位文件
    • 拷貝master上的ssl證書到node
    • 部署kubelet
    • 部署kube-proxy

先將k8s-normal-master.zip文件上傳到master和node節點上並解壓,如果節點已安裝docker先執行卸載老版本

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

修改shell文件夾下面的init.sh腳本文件,按照下面修改兩處地方

#修改host內容為我們
echo "192.168.50.33 k8s-master-1" >> /etc/hosts
echo "192.168.50.34 k8s-node-1" >> /etc/hosts
echo "192.168.50.35 k8s-node-2" >> /etc/hosts
#找出最新版本 
yum list docker-ce --showduplicates | sort -r
yum list docker-ce-cli --showduplicates | sort -r
#修改為最新的版本
yum -y install docker-ce-20.10.8 docker-ce-cli-20.10.8 containerd.io
#設置hosts須手動修改,並授予init
#master-1節點上執行
sh init.sh  k8s-master-1
#node1節點上執行
sh init.sh  k8s-node-1
#node2節點上執行
sh init.sh  k8s-node-2

至此,三台伺服器的docker安裝已安裝完畢

image-20210914182048254

image-20210914183830942

image-20210914183856188

證書生成執行步驟

修改mktls.sh裡面hosts為我們部署節點host

cat > server-csr.json <<EOF
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "192.168.50.33",
      "192.168.50.34",
      "192.168.50.35",
      "10.10.0.1",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF
#在master節點上執行
sh mktls.sh
# 將生成的證書相關的文件copy到所有node機器上
scp -r /k8s/kubernetes/ssl/*  [email protected]:/k8s/kubernetes/ssl
scp -r /k8s/kubernetes/ssl/*  [email protected]:/k8s/kubernetes/ssl

image-20210914185324206

部署Etcd集群執行步驟

修改etcd_install.sh腳本etcd版本為最新的v3.5.0

# 修改為etcd最新版本
wget //github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz
tar zxvf etcd-v3.5.0-linux-amd64.tar.gz
cd etcd-v3.5.0-linux-amd64
# master節點上執行
sh etcd_install.sh
# master節點創建目錄
mkdir /opt/package-k8s
# 將所有二級制文件下載到該目錄下
cd /opt/package-k8s
# cpoy 執行文件到 /opt/kubernetes/bin 目錄,並對所有文件增加可執行的許可權
cp -a kube-apiserver kube-controller-manager kube-scheduler kubectl kubelet kube-proxy /k8s/kubernetes/bin

image-20210915103728485

# 修改kubeconfig.sh部分內容,根據實際情況修改KUBE_APISERVER地址
export KUBE_APISERVER="//192.168.50.33:6443"
#執行配置腳本
sh kubeconfig.sh

image-20210915105502442

#拷貝目錄到所有節點上
scp -r /k8s/* [email protected]:/k8s/
scp -r /k8s/* [email protected]:/k8s/
# master節點上執行etcd配置命令
sh etcd_conf.sh etcd01 192.168.50.33 etcd01=//192.168.50.33:2380,etcd02=//192.168.50.34:2380,etcd03=//192.168.50.35:2380

# node1節點上執行etcd配置命令
sh etcd_conf.sh etcd02 192.168.50.34 etcd01=//192.168.50.33:2380,etcd02=//192.168.50.34:2380,etcd03=//192.168.50.35:2380

# node2節點上執行etcd配置命令
sh etcd_conf.sh etcd03 192.168.50.35 etcd01=//192.168.50.33:2380,etcd02=//192.168.50.34:2380,etcd03=//192.168.50.35:2380

# etcd健康檢查
ETCDCTL_API=3 /k8s/etcd/bin/etcdctl  --write-out=table \
--cacert=/k8s/kubernetes/ssl/ca.pem --cert=/k8s/kubernetes/ssl/server.pem --key=/k8s/kubernetes/ssl/server-key.pem \
--endpoints=//192.168.50.33:2379,//192.168.50.34:2379,//192.168.50.35:2379 endpoint health

image-20210915110805343

部署Master Node執行步驟

修改apiserver.sh中內容

#去掉kubelet-https
--kubelet-https=true \\
##增加service-accoun配置
--service-account-issuer=kubernetes.default.svc \\
--service-account-signing-key-file=/k8s/kubernetes/ssl/ca-key.pem \\

去掉controller-manager.sh中內容–feature-gates=RotateKubeletClientCertificate=true \

#master節點配置apiserver
sh apiserver.sh 192.168.50.33 //192.168.50.33:2379,//192.168.50.34:2379,//192.168.50.35:2379 
#master節點配置controller-manager
sh controller-manager.sh 127.0.0.1
#master節點配置scheduler
sh scheduler.sh 127.0.0.1
# 查看master三個服務是否正常運行
ps -ef | grep kube
netstat -ntpl | grep kube-

image-20210915134900751

準備admin證書配置 admin-csr.json,放在 admin目錄

{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "XS",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

使用根證書(ca.pem)簽發admin證書

cfssl gencert \
        -ca=/k8s/kubernetes/ssl/ca.pem \
        -ca-key=/k8s/kubernetes/ssl/ca-key.pem \
        -config=/k8s/kubernetes/ssl/ca-config.json \
        -profile=kubernetes admin-csr.json | cfssljson -bare admin

image-20210915154545356

#指定apiserver的地址和證書位置(ip自行修改)
kubectl config set-cluster kubernetes \
        --certificate-authority=/k8s/kubernetes/ssl/ca.pem \
        --embed-certs=true \
        --server=//192.168.50.36:6443
#設置客戶端認證參數,指定admin證書和秘鑰
kubectl config set-credentials admin \
        --client-certificate=/k8s/kubernetes/ssl/admin/admin.pem \
        --embed-certs=true \
        --client-key=/k8s/kubernetes/ssl/admin/admin-key.pem	
#關聯用戶和集群
kubectl config set-context kubernetes \
        --cluster=kubernetes --user=admin
#設置當前上下文
kubectl config use-context kubernetes
#查看組件的狀態測試下
kubectl get cs
#查看pod
kubectl get pods

image-20210915154855004

image-20210915155141845

暫時先到這裡,其他部署後續有時間我們再繼續,本篇我們主要還是學習命令和部署實戰

容器編排部署實戰

nginx部署示例

所有命令不清楚就是用–help這個萬能的神命令查看,這裡採用deployment部署,當然也可以單獨創建pod,這種在實際場景會比較少用

#創建nginx部署
kubectl create deployment nginx --image=nginx
#暴露埠 type類型可以有多種
kubectl expose deployment nginx --port=80 --type=NodePort
#查看pods和services的資訊,這裡是縮寫,其他縮寫可以查詢--help命令,像上面deployment縮寫為deploy,對應複數可是可以使用,一般使用簡寫
kubectl get pod,svc -o wide

image-20210916173451992

上面有幾個Ip和埠需要理解下。k8s-node-1的ip是192.168.50.34,宿主機上的埠為32173,所以我們可以通過//192.168.50.34:32173 訪問到這個pod暴露的服務

image-20210916173643231

#更新鏡像版本
kubectl set image deploy nginx nginx=nginx:1.7.9
#查看更新狀態
kubectl rollout status deploy nginx
#describe顯示特定資源或資源組的詳細資訊,這裡顯示nginx部署詳細資訊
kubectl describe deploy nginx

image-20210917141923017

#回退到上一次的版本
kubectl rollout undo deploy nginx
#查看deployment變更的對應版本
kubectl rollout history deploy nginx
#查看deployment變更的對應版本的細節
kubectl rollout history deploy nginx --revision=7
#回滾到指定的版本
kubectl rollout undo deploy nginx --to-revision=7

# kubectl proxy主要用於測試,可以通過
kubectl proxy
curl //localhost:8001/api/v1/proxy/namespaces/default/pods/podname訪問

image-20210917151457981

容器擴縮容示例

#擴容nginx pod數量為4
kubectl scale deploy nginx --replicas=4
#查看pod資訊,第一次查詢結果k8s-node-1上pod馬上就有,應該k8s-node-1之前下載了nginx鏡像,第二次k8s-node-2下載完鏡像也啟動兩個pod,k8s有自己的演算法比較均衡將pod分布集群節點上
kubectl get pod -o wide
#縮容nginx pod數量為2,
kubectl scale deploy kubernetes-bootcamp --replicas=2

image-20210917143610845

基於yaml文件方式部署

上面我們都是基於kubectl也即是命令方式直接創建deployment和pod、service,這種方式一般是簡單測試使用,接下來我們基於yaml文件方式部署

編寫單獨創建pod的yaml文件nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.7.9
      ports:
      - containerPort: 80
# 通過create命令用yaml來創建pod,另外還可以使用apply命令用yaml來創建
kubectl create -f nginx-pod.yaml

image-20210917145919844

編寫創建deploy的yaml文件nginx-deploy.yaml,也可以直接通過下面命令生成一個deployment的yaml文件

kubectl create deployment nginx-d1 --image=nginx:1.18 -o yaml --dry-run > nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx-deploment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.18
        name: nginx
        resources: {}
status: {}
#刪除deployment
kubectl delete deploy nginx
# 基於yaml創建deployment
kubectl apply -f nginx-deploy.yaml
#查看labels標籤為app=nginx的pod,上面選擇器為app=nginx,我們創建多個pod,找到label,services也是根據這個label找到然後做負載均衡
kubectl get pods -l app=nginx
#可以查看pod的日誌,和我們之前docker logs一樣
kubectl logs pod -f

image-20210917153236540

接下來我們看下service部分,也即是kubernetes的ingress來暴露應用,創建nginx-service.yaml文件

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
  - port: 8080
    targetPort: 80
    nodePort: 30080
  selector:
    app: nginx
  type: NodePort

#創建service
kubectl create -f nginx-service.yaml
#查看創建service詳細資訊,安裝完系統有一個名稱為kubernetes的service,這個相當把apiserver做成一個ip
kubectl describe service nginx-service

image-20210917154618381

有幾個重要埠我們一起來了解下

  • nodePort:這個是提供給集群外部的集群訪問的,像這類配置為30080則可以提供給外部訪問,比如這裡直接訪問//192.168.50.34:30080,service內部實現服務發現和負載均衡

image-20210917155331649

  • targetPort:容器的埠,與製作容器鏡像時暴露埠一致,和我們之前學習docker製作dockerfile文件是一樣的,例如我們這裡的測試的nginx,docker.io官方鏡像暴露埠就是80
  • port:這個是kubernetes集群內部各個服務之間互相訪問的埠,比如我們mysql容器雖然暴露3306埠,沒有配置nodePort,外部無法直接訪問容器,但集群內部容器之間是可以通過訪問mysql服務

我們可以進入任意一個容器進行測試,我們進入到kubernetes-bootcamp,然後訪問nginx的pod服務

#由於目前這個容器只有一個pod
kubectl exec -it kubernetes-bootcamp /bin/bash
#如果有多個pod,那就需要通過docker命令找到容器的名稱指定了
kubectl exec -it kubernetes-bootcamp --container xxxxx /bin/bash
#進入一個裝有工具箱的環境,一般用於測試
kubectl run busybox --rm=true --image=busybox --restart=Never --tty -i

image-20210917160859014

生成10.20網段的地址是容器內的地址,10.10網段是用於集群內容通訊的地址,也可以pod直接訪問 ,比如我們這裡的//10.10.11.146

image-20210917175759484

image-20210917175741729

基於dns訪問集群

#查詢所有命名空間的service,kube-dns集群地址為10.10.0.10,這個是kubeadm創建dns服務
kubectl  get svc -A
#如果是手動安裝我們可以通過apply方式部署dns,kube-dns.yaml,下載地址可以網上找,比如//github.com/liuyi01/kubernetes-starter/blob/master/kubernetes-with-ca/services/kube-dns.yaml
kubectl apply -f kube-dns.yaml

image-20210918092423301

可以通過nginx-service名稱訪問到nginx的服務

image-20210918093901511

安裝儀錶盤

# 下載 dashboard.yaml 文件到本地,可以在github kubernetes dashboard項目上查看最新版本,目前U最新版本為v2.3.1
wget //raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
kubectl apply -f recommended.yaml
kubectl proxy

image-20210916175926722

# 設置可以在外部訪問dashboard,修改 dashboard以 nodePort 訪問,編輯配置文件
kubectl -n kubernetes-dashboard edit service kubernetes-dashboard
修改類型
type: ClusterIP 
改為
type: NodePort
#查看暴露的埠
kubectl -n kubernetes-dashboard get service kubernetes-dashboard

image-20210916180136840

通過節點訪問//192.168.50.34:30109/#/login 頁面

image-20210916180556615

在我們上面下載recommended.yaml文件裡面就有subjects,表示創建了 kubernetes-dashbord 賬戶

image-20210917162233195

# 為該賬戶創建登錄 token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep kubernetes-dashboard | awk '{print $1}')

Data
====
ca.crt:     1099 bytes
namespace:  20 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6Im5EOGxxZHFIdnFKeTRabmlicHhRNDVBZ3Y0WlR1enRLQkdoZ21EcFExLWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi1xenNiayIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjcyNGQ0ODRmLTY2M2YtNGM2YS1hNGMyLTVlOTk3OTliYzczMyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.czIcgip4VJe7dEY_nulArhqKtd2Lc3JGlUrNmn4jGc2ZZ5TMeluRvv71Sztdmb-iYftWKnqil-OuCBgTFss6atShfiQ3__2i4V-vBAM1cFjBtxKZ0QgOpRvDri0hAj34XnF9uSzjH24Gt4x50OX9qaIKmJ8ppHVe0lxBWXP-Z-N4JbrKkRbD6c-EwYBhMoJo7ndUGmkxVsCvuNaE4yRfXENRaunPmGYJMgvFo4XSAz37cznNNVVj8BaIbSxgxv8XPgUEdQZxP2bm2TskVb3AYqeSVd4YR87NxYFod91IezRUBelbupaVWllJVcsEIaANfk4NNN61atWkGO9aNgyK4Q

將上面的token複製,點擊登錄即可

image-20210917163000126

到此我們初步了解k8s及簡單命令,後續再學習k8s進階內容、例如configmap、secrets、有狀態應用、高可用k8s集群、helm以及基於微服務集群容器編排部署實戰等