搭建K8S集群(kubeadm篇)


搭建K8S集群(kubeadm篇)

一、K8S概述

K8S是當下最火熱的容器運行時編排工具,不僅僅提供了用戶應用的容器鏡像運行解決方案,還提供了路由網關、水平擴展、多副本容災等能力。在Kubernetes項目中,master節點由負責api服務的kube-apiserver、負責調度的kube-scheduler、負責編排的kebu-controller-manager三者組成。node節點上,最核心的部分是kubelet組件。kubelet主要負責同容器運行時(比如Docker項目)交互,而交互依賴的是CRI(Container Runtime Interface)的遠程調用接口。這個接口定義了容器運行時的各項核心操作。具體的容器運行時,則通過OCI這個容器標准,把CRI請求翻譯成對Linux系統的底層調用。
話不多說,我們用最簡單的方式,即kubeadm來搭建一個K8S集群吧。

二、如何使用kubeadm搭建集群

2.1 機器准備

我們需要准備3台機器,配置是4核8G,提前做好部署規划和網絡規划。考慮到雲上機器的網絡條件較好,我這里用的是騰訊雲的機器,讀者們也可以使用3台2核4G的機器來完成搭建。
每台機器都需要關閉防火牆,配置好DNS域名解析,並且時間上已配置同步。

  • master節點
  • node1節點
  • node2節點

2.2 准備程序包

由於我們本次使用的是kubeadm工具搭建集群,我們先要下載相關的程序包。但是!由於大中華網絡等原因,部分包下載會有問題。那怎么辦呢,我們找一台海外的機器來下載這部分程序包即可。
安裝kubeadm所需的程序包有以下幾個

  • kubelet
  • kubeadm
  • kubectl
  • kubernetes-cni
  • cri-tools
# 安裝yum-utils工具,這樣我們就可以將包下載到本地
yum install -y yum-utils

# 配置yum源,讓我們能夠下載相關程序包
cat >> /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=http://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=http://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

# 將相關程序包下載 kubelet kubeadm kubectl kubernetes-cni cri-tools
yumdownloader kubelet kubeadm kubectl kubernetes-cni cri-tools

# 打包這幾個rpm程序包,上傳到我們的集群機器上去
tar zcf k8s-deploy.tgz *.rpm

備注: 作者知道有些同學可能還沒有海外的服務器,這幾個服務的包我已經打包好放在網盤上,大家可以直接下載使用。https://share.weiyun.com/g8sbwcWA

2.3 安裝kubeadm

我們已經有了相關軟件包了,安裝就很簡單了

# 解壓軟件包
tar xf k8s-deploy.tgz

# 執行安裝
yum localinstall -y *.rpm

2.4 下載鏡像

最早期的時候,K8S集群是直接部署在裸金屬服務器上面的,這個部署過程有一系列繁瑣的操作(如手動生成配置證書等操作),非常的不友好。后面呢大家考慮,既然K8S能力這么強大,那為何不把kube-apiserver、kube-controller-manager、kube-scheduler這些都做成容器鏡像,然后通過K8S直接管理起來呢。事實上,kubeadm就是這樣做的。但是這里有一點需要注意的是,並不是每個組件都事宜做成容器鏡像的,比方說像kubelet。因為kubelet需要與宿主機打交道,比方說配置宿主機網絡、存儲系統等。假如kubelet是一個容器,那么其運行在自己的Namespace中,是很難對宿主機進行操作的。因此,kubelet是需要手動在宿主機上安裝的。
我們開始下載K8S組件的容器鏡像,糟糕這里似乎有被大中華的網絡攔截了。這里我們就需要依賴阿里雲鏡像倉庫,這里有我們所需的全部鏡像,我們可以從阿里雲鏡像倉庫下載鏡像,然后打tag將鏡像改成kubeadm所需的即可。

# 查看kubeadm部署集群所需的鏡像
kubeadm config images list
#k8s.gcr.io/kube-apiserver:v1.23.1
#k8s.gcr.io/kube-controller-manager:v1.23.1
#k8s.gcr.io/kube-scheduler:v1.23.1
#k8s.gcr.io/kube-proxy:v1.23.1
#k8s.gcr.io/pause:3.6
#k8s.gcr.io/etcd:3.5.1-0
#k8s.gcr.io/coredns/coredns:v1.8.6

# 下載所需鏡像並修改tag,這里的coredns我們稍后單獨處理
for item in `kubeadm config images list | egrep -v "coredns|grep"` ; do image=` echo $item | sed -e "s@k8s.gcr.io@registry.aliyuncs.com/google_containers@g"`; docker pull $image ; docker tag $image `echo $image | sed -e "s@registry.aliyuncs.com/google_containers@k8s.gcr.io@g"` ; docker rmi $image ; done ; 

# 下載coredns鏡像
for item in `kubeadm config images list | egrep "coredns" | grep -v grep ` ; do image=` echo $item | sed -e "s@k8s.gcr.io/coredns@registry.aliyuncs.com/google_containers@g"` ; docker pull $image ; docker tag $image `echo $image | sed -e "s@registry.aliyuncs.com/google_containers@k8s.gcr.io/coredns@g"` ; docker rmi $image ; done ; 

# 查看我們下載的所有鏡像,此時看看是不是和我們通過kubeadm config images list查詢出來的一樣啦
docker images

2.5 部署master節點

到了這里,我們就可以使用kubeadm來部署master節點。部署命令非常簡單,只需要執行kubeadm init即可。部署完成之后,出現如下提示就說明kubeadm執行完成了。

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

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 IP:6443 --token ltfaw0.yci1z7zqdrll2ixp \
        --discovery-token-ca-cert-hash sha256:145415d491d67daeb13910ffb49e5a8608863225a13cfdc794b85cc5aca46972 

在這里可能有些同學會碰到kubelet相關的異常,通過執行journalctl -xeu kubelet可以看到,最常見的就是kubelet提示“kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs"”,這是什么意思呢?
意思就是說docker使用的cgroup驅動和kubelet使用的驅動不一致,我們知道cgroup全稱為Linux Control Group,是用來控制一個進程組使用系統資源的上限。kubelet是通過CRI這個遠程調用接口來操作容器運行時(即Docker),驅動不一致會導致相關限制能力無法執行。所以,我們需要修改Docker(建議,當然也可以修改kubelet)的cgroup驅動。具體如下:

# 修改docker的配置文件
cat /etc/docker/daemon.json 
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}

# 內核重新加載進程配置
systemctl daemon-reload

# 重啟docker進程
systemctl restart docker

# 檢查docker的cgroup驅動
docker info

2.6 部署網絡插件

此時我們部署好了K8S集群的master節點,根據輸出提示export KUBECONFIG=/etc/kubernetes/admin.conf在機器上執行,然后我們通過kubectl get po -n kube-system檢查各個Pod的運行情況。突然發現咋不對勁呢,怎么有些Pod始終處於Pending狀態呢?

[root@VM-62-206-centos ~]# kubectl get po -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
coredns-64897985d-9nrqf                    0/1     Pending   0          31s
coredns-64897985d-ms4jr                    0/1     Pending   0          31s
etcd-vm-62-206-centos                      1/1     Running   0          35s
kube-apiserver-vm-62-206-centos            1/1     Running   0          35s
kube-controller-manager-vm-62-206-centos   1/1     Running   0          37s
kube-proxy-zkxln                           1/1     Running   0          31s
kube-scheduler-vm-62-206-centos            1/1     Running   0          35s

其實這是正常的,DNS和什么相關,和網絡相關對吧。我們現在都還沒有網絡插件,肯定是有問題啊。話不多說,我們立馬把網絡插件部署上去,在這里我們使用的網絡插件是weave

# 部署網絡插件,非常簡單一條命令就可以搞定
# 執行完之后需要等一段時間,因為在下載鏡像
kubectl apply -n kube-system -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

這里可能有些同學在部署過程中會碰到,網絡插件weave在啟動的過程在提示“CrashLoopBackOff”,我們打開日志檢查

kubectl logs weave-net-k966t -c weave -n kube-system
# Network 10.32.0.0/12 overlaps with existing route 10.0.0.0/8 on host

我們從這里看到了啥,是不是說weave需要配置10.32.0.0/12這個網段的路由表,但是和現有機器上面的路由表沖突了。怎么辦呢,其實比較簡單的解決辦法是把現有沖突的網段調整一下。調整完之后,我們再打印下Pod運行情況,可以看到Pod全部都正常運行了。

kubectl get po -n kube-system
NAME                                       READY   STATUS    RESTARTS       AGE
coredns-64897985d-9nrqf                    1/1     Running   0              92m
coredns-64897985d-ms4jr                    1/1     Running   0              92m
etcd-vm-62-206-centos                      1/1     Running   0              92m
kube-apiserver-vm-62-206-centos            1/1     Running   0              92m
kube-controller-manager-vm-62-206-centos   1/1     Running   0              92m
kube-proxy-zkxln                           1/1     Running   0              92m
kube-scheduler-vm-62-206-centos            1/1     Running   0              92m
weave-net-k966t                            2/2     Running   11 (21m ago)   59m

2.7 部署node節點

部署node節點比較簡單,我們在node節點上面安裝好docker-ce、kubeadm、上傳相關鏡像后,只需要將部署master節點系統提示的命令復制過去即可。

# 執行部署node節點命令
kubeadm join IP:6443 --token ltfaw0.yci1z7zqdrll2ixp --discovery-token-ca-cert-hash sha256:145415d491d67daeb13910ffb49e5a8608863225a13cfdc794b85cc5aca46972 

此時我們等一段時間,等待weave插件在node節點上面安裝完成,就可以看到整個集群Pod均運行情況。

kubectl get po -n kube-system
NAME                                       READY   STATUS    RESTARTS       AGE
coredns-64897985d-9nrqf                    1/1     Running   0              130m
coredns-64897985d-ms4jr                    1/1     Running   0              130m
etcd-vm-62-206-centos                      1/1     Running   0              130m
kube-apiserver-vm-62-206-centos            1/1     Running   0              130m
kube-controller-manager-vm-62-206-centos   1/1     Running   0              130m
kube-proxy-ftr7m                           1/1     Running   0              30m
kube-proxy-mcxt5                           1/1     Running   0              29m
kube-proxy-zkxln                           1/1     Running   0              130m
kube-scheduler-vm-62-206-centos            1/1     Running   0              130m
weave-net-9rpsv                            2/2     Running   0              30m
weave-net-dd9nr                            2/2     Running   0              29m
weave-net-k966t                            2/2     Running   11 (58m ago)   97m

2.8 一些收尾工作

到目前為止,我們已經部署好一個非生產環境的K8S集群,做做實驗還是綽綽有余的。不過,大家有沒有發現,kubectl命令只有在master節點上管用,在其他的node節點似乎不起作用,始終提示“The connection to the server localhost:8080 was refused - did you specify the right host or port?”。這個如何修復呢,其實很簡單,我們只需要把master節點的/etc/kubernetes/admin.conf拷貝到node節點的對應位置,在執行export命令即可。

scp /etc/kubernetes/admin.conf root@node_ip:/etc/kubernetes/admin.conf
export KUBECONFIG=/etc/kubernetes/admin.conf

三、控制器模式下運行Pod實例

現在我們已經有了完整可用的K8S集群,我們就開始部署一個簡答的Nginx服務吧。

3.1 編寫YAML文件

我已經編寫好一個最簡單的案例文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

3.2 運行應用

我們執行kubectl apply -f nginx.yaml來將我們編寫好的YAML提交到K8S,使用apply操作的好處在於,K8S可以自動識別到文件的變化,並根據對象的變化自動執行響應的操作(增加或者減少副本數量、修改應用鏡像等)。
過了幾分鍾,我們可以看到應用順利運行起來了。

kubectl get po
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5fcc5d8c6d-6fr2b   1/1     Running   0          12m
nginx-deployment-5fcc5d8c6d-79r2w   1/1     Running   0          11m


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM