主頁 > 後端開發 > Kubernetes容器編排探索與實踐v1.22.1-上半部分

Kubernetes容器編排探索與實踐v1.22.1-上半部分

2021-10-11 07:38:56 後端開發

概述

**本人博客網站 **IT小神 www.itxiaoshen.com

Kubernetes官網地址 https://kubernetes.io

Kubernetes GitHub原始碼地址 https://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 名稱,并且可以在它們之間實作負載均衡,
  • 存盤編排

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

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

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

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

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

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

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

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

kubernetes使用

檔案

kubernetes中文檔案地址 https://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": ["https://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=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://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 https://docs.projectcalico.org/manifests/calico.yaml          
#或者選擇kube-flannel網路
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#過兩分鐘后再查看節點的狀態

image-20210916170305883

image-20210917230153343

image-20210917230304013

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

#calico.yaml先下載下來
wget https://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 https://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="https://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=https://192.168.50.33:2380,etcd02=https://192.168.50.34:2380,etcd03=https://192.168.50.35:2380

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

# node2節點上執行etcd配置命令
sh etcd_conf.sh etcd03 192.168.50.35 etcd01=https://192.168.50.33:2380,etcd02=https://192.168.50.34:2380,etcd03=https://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=https://192.168.50.33:2379,https://192.168.50.34:2379,https://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 https://192.168.50.33:2379,https://192.168.50.34:2379,https://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=https://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,所以我們可以通過http://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 http://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則可以提供給外部訪問,比如這里直接訪問http://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直接訪問 ,比如我們這里的http://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,下載地址可以網上找,比如https://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 https://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

通過節點訪問https://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
=https://www.cnblogs.com/itxiaoshen/p/===
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以及基于微服務集群容器編排部署實戰等

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/308199.html

標籤:Go

上一篇:【golang詳解】go語言GMP(GPM)原理和調度

下一篇:Ebiten-純Golang開發的跨平臺游戲引擎

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more