kubernetes系列:(一)、kubeadm搭建kubernetes(v1.13.1)單節點集群


kubeadm是Kubernetes官方提供的用於快速部署Kubernetes集群的工具,本篇文章使用kubeadm搭建一個單master節點的k8s集群。

節點部署信息

節點主機名 節點IP 節點角色 操作系統
k8s-master 10.10.55.113 master centos7.6
k8s-node1 10.10.55.114 node centos7.6

 

 

 

 

節點說明

master:控制節點。kube-apiserver負責API服務,kube-controller-manager負責容器編排,kube-scheduler負責調度

node:工作節點。kubelet 主要負責同容器運行時(比如 Docker 項目)打交道。而這個交互所依賴的,是一個稱作 CRI(Container Runtime Interface)的遠程調用接口,這個接口定義了容器運行時的各項核心操作,比如:啟動一個容器需要的所有參數

master核心組件 node核心組件
kube-apiserver kubelet
kube-controller-manager  
kube-scheduler  

 

 

 

 

 

一、基礎環境准備

以下操作無特殊說明均在每個節點執行。

修改主機名

#master節點:
hostnamectl set-hostname k8s-master
#node1節點:
hostnamectl set-hostname k8s-node1

基本配置

#修改/etc/hosts文件
cat >> /etc/hosts << EOF
10.10.55.113 k8s-master
10.10.55.114 k8s-node1
EOF

#關閉防火牆和selinux
systemctl stop firewalld && systemctl disable firewalld
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0

#關閉swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab

設置網橋包經過iptalbes

RHEL / CentOS 7上的一些用戶報告了由於iptables被繞過而導致流量路由不正確的問題。創建/etc/sysctl.d/k8s.conf文件,添加如下內容:

cat <<EOF >  /etc/sysctl.d/k8s.conf
vm.swappiness = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# 使配置生效
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf

修改iptables filter表中FOWARD鏈的默認策略(pllicy)為ACCEPT 

iptables -P FORWARD ACCEPT

kube-proxy開啟ipvs的前提條件

由於ipvs已經加入到了內核的主干,所以為kube-proxy開啟ipvs的前提需要加載以下的內核模塊:
在所有的Kubernetes節點執行以下腳本:

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF

#執行腳本
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

#查看是否已經正確加載所需的內核模塊
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

上面腳本創建了/etc/sysconfig/modules/ipvs.modules文件,保證在節點重啟后能自動加載所需模塊。 使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已經正確加載所需的內核模塊。
接下來還需要確保各個節點上已經安裝了ipset軟件包。 為了便於查看ipvs的代理規則,最好安裝一下管理工具ipvsadm。

yum install ipset
yum install ipset ipvsadm -y

安裝docker

Kubernetes默認的容器運行時仍然是Docker,使用的是kubelet中內置dockershim CRI實現。需要注意的是,Kubernetes 1.13最低支持的Docker版本是1.11.1,最高支持是18.06,而Docker最新版本已經是18.09了,故我們安裝時需要指定版本為18.06.1-ce

#配置docker yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#安裝指定版本,這里安裝18.06
yum list docker-ce --showduplicates | sort -r
yum install -y docker-ce-18.06.1.ce-3.el7
systemctl start docker && systemctl enable docker

#啟用docker
systemctl enable docker
sudo systemctl start docker

#測試docker是否安裝成功
docker run hello-world

安裝kubeadm、kubelet、kubectl

官方安裝文檔可以參考:
https://kubernetes.io/docs/setup/independent/install-kubeadm/

kubelet 在群集中所有節點上運行的核心組件, 用來執行如啟動pods和containers等操作。
kubeadm 引導啟動k8s集群的命令行工具,用於初始化 Cluster。
kubectl 是 Kubernetes 命令行工具。通過 kubectl 可以部署和管理應用,查看各種資源,創建、刪除和更新各種組件。

#配置kubernetes.repo的源,由於官方源國內無法訪問,這里使用阿里雲yum源
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

#在所有節點上安裝指定版本 kubelet、kubeadm 和 kubectl
yum install -y kubelet-1.13.1 kubeadm-1.13.1 kubectl-1.13.1

#啟動kubelet服務
systemctl enable kubelet && systemctl start kubelet

二、部署master節點

Master節點執行初始化:

注意這里執行初始化用到了- -image-repository選項,指定初始化需要的鏡像源從阿里雲鏡像倉庫拉取。--ignore-preflight-errors=Swap,忽略系統swap錯誤警告

kubeadm init \
   --kubernetes-version=v1.13.1 \
   --pod-network-cidr=10.244.0.0/16 \
   --image-repository registry.aliyuncs.com/google_containers \
   --apiserver-advertise-address=10.10.55.113 \
   --ignore-preflight-errors=Swap

等待執行完成后,會看到類似如下的提示,后續加入kubernetes集群要用到

kubeadm join 10.10.55.113:6443 --token x66sy3.7e2u4um7etb3zk57 --discovery-token-ca-cert-hash sha256:147a0920ac265d668e54fea59af4fb570660eccd178ca1c247c0c018286478a3

配置 kubectl

kubectl 是管理 Kubernetes Cluster 的命令行工具,前面我們已經在所有的節點安裝了 kubectl。Master 初始化完成后需要做一些配置工作,然后 kubectl 就能使用了。
依照 kubeadm init 輸出的最后提示,推薦用 Linux 普通用戶執行 kubectl。

創建普通用戶centos

#創建普通用戶並設置密碼123456
useradd centos && echo "centos:123456" | chpasswd centos

#追加sudo權限,並配置sudo免密
sed -i '/^root/a\centos  ALL=(ALL)       NOPASSWD:ALL' /etc/sudoers

#保存集群安全配置文件到當前用戶.kube目錄
su - centos
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

#啟用 kubectl 命令自動補全功能(注銷重新登錄生效)
echo "source <(kubectl completion bash)" >> ~/.bashrc

需要這些配置命令的原因是:Kubernetes 集群默認需要加密方式訪問。所以,這幾條命令,就是將剛剛部署生成的 Kubernetes 集群的安全配置文件,保存到當前用戶的.kube 目錄下,kubectl 默認會使用這個目錄下的授權信息訪問 Kubernetes 集群。
如果不這么做的話,我們每次都需要通過 export KUBECONFIG 環境變量告訴 kubectl 這個安全配置文件的位置。
配置完成后centos用戶就可以使用 kubectl 命令管理集群了。

查看集群狀態:

確認各個組件都處於healthy狀態。

[root@k8s-master ~]# kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
controller-manager   Healthy   ok
scheduler            Healthy   ok
etcd-0               Healthy   {"health": "true"}

部署網絡插件(這里使用flannerl)

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

kubectl apply -f  kube-flannel.yml

安裝完成確保所有pod處於running狀態

kubectl get pod --all-namespaces -o wide

#或者如下命令(-n kube-system意思為命名空間kube-system下pod的狀態)
kubectl get pods -n kube-system

此時master節點的狀態為ready

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   8d    v1.13.1

安裝出現問題

#日志 (coredns-78d4cf999f-qhb7p指 pod的name)
kubectl logs coredns-78d4cf999f-qhb7p -n kube-system

#節點詳情
kubectl describe pods coredns-78d4cf999f-qhb7p -n kube-system

嘗試重新安裝

kubeadm reset

ifconfig cni0 down
ip link delete cni0

ifconfig flannel.1 down
ip link delete flannel.1

rm -rf /var/lib/cni/

三、部署node節點

node加入kubernetes集群

#執行以下命令將節點接入集群
kubeadm join 10.10.55.113:6443 --token x66sy3.7e2u4um7etb3zk57 --discovery-token-ca-cert-hash sha256:147a0920ac265d668e54fea59af4fb570660eccd178ca1c247c0c018286478a3
#如果執行kubeadm init時沒有記錄下加入集群的命令,可以通過以下命令重新創建 kubeadm token create --print-join-command

查看節點狀態

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   8d    v1.13.1
k8s-node1    Ready    <none>   8d    v1.13.1

確保組件為running

[root@k8s-node1 ~]# kubectl get pods -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-78d4cf999f-77ql5             1/1     Running   0          8d
coredns-78d4cf999f-qhb7p             1/1     Running   0          8d
etcd-k8s-master                      1/1     Running   0          8d
kube-apiserver-k8s-master            1/1     Running   0          8d
kube-controller-manager-k8s-master   1/1     Running   1          8d
kube-flannel-ds-amd64-2272z          1/1     Running   0          8d
kube-flannel-ds-amd64-zlgxf          1/1     Running   0          8d
kube-proxy-hwptn                     1/1     Running   0          8d
kube-proxy-p6cg2                     1/1     Running   0          8d
kube-scheduler-k8s-master            1/1     Running   1          8d

如果pod狀態為Pending、ContainerCreating、ImagePullBackOff 都表明 Pod 沒有就緒,Running 才是就緒狀態。
如果有pod提示失敗,我們可以通過 kubectl describe pod 查看 Pod 具體情況,以具體分析解決問題

四、測試集群各個組件是否正常

 首先驗證kube-apiserver, kube-controller-manager, kube-scheduler, pod network 是否正常:
部署一個 Nginx Deployment,包含2個Pod

[root@k8s-node1 ~]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-saas-service 1/1 1 1 5d5h
my-saas-web 1/1 1 1 3d23h
[root@k8s-node1 ~]# kubectl create deployment nginx --image=nginx:alpine
deployment.apps/nginx created
[root@k8s-node1 ~]# kubectl scale deployment nginx --replicas=2
deployment.extensions/nginx scaled
[root@k8s-node1 ~]# kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-54458cd494-cgqgf 1/1 Running 0 13s 10.244.1.36 k8s-node1 <none> <none>
nginx-54458cd494-gkhlb 1/1 Running 0 8s 10.244.1.37 k8s-node1 <none> <none>

再驗證一下kube-proxy是否正常:

以 NodePort 方式對外提供服務

[root@k8s-node1 ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
[root@k8s-node1 ~]# kubectl get services nginx
NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
nginx   NodePort   10.102.34.74   <none>        80:31782/TCP   4s

可以通過任意 NodeIP:Port 在集群外部訪問這個服務:

[root@k8s-node1 ~]# curl 10.10.55.113:31782
[root@k8s-node1 ~]# curl 10.10.55.114:31782
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

最后驗證一下dns, pod network是否正常:

 運行Busybox並進入交互模式

[root@k8s-node1 ~]# kubectl run -it curl --image=radial/busyboxplus:curl
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.
If you don't see a command prompt, try pressing enter.

輸入nslookup nginx查看是否可以正確解析出集群內的IP,以驗證DNS是否正常

[ root@curl-66959f6557-rb2bm:/ ]$ nslookup nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx
Address 1: 10.102.34.74 nginx.default.svc.cluster.local

通過服務名進行訪問,驗證kube-proxy是否正常

[ root@curl-66959f6557-rb2bm:/ ]$ curl http://nginx/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
  ...
</body>
</html>

退出 exit

kube-proxy開啟ipvs

修改ConfigMap的kube-system/kube-proxy中的config.conf,mode: “ipvs”:

kubectl edit cm kube-proxy -n kube-system

之后重啟各個節點上的kube-proxy pod:

kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'

查看狀態

kubectl get pod -n kube-system | grep kube-proxy

查看日志

kubectl logs kube-proxy-pf55q -n kube-system

日志中打印出了Using ipvs Proxier,說明ipvs模式已經開啟。

備注:刪除節點和集群

如何從集群中移除k8s-node2 (是k8s-node2)?

首先要排除節點,並確保該節點為空, 然后再將其關閉。

1. 在master節點上執行:

kubectl drain k8s-node2   --delete-local-data --force --ignore-daemonsets
kubectl delete node k8s-node2  

2. 在子節點k8s-node2  上執行:

kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/

3.在子節點 k8s-node1上執行

kubectl delete node k8s-node2 

注意:

在master上刪除node並不會清理k8s-node2運行的容器,需要在刪除節點上面手動運行清理命令。
如果你想重新配置集群,使用新的參數重新運行kubeadm init或者kubeadm join即可。

 

到此,kubeadm搭建kubernetes(v1.13.1)單節點集群搭建完成,后續可以繼續添加node節點,或者部署dashboard、helm包管理工具、EFK日志系統、Prometheus Operator監控系統、rook+ceph存儲系統等組件

參考:

https://blog.csdn.net/networken/article/details/84991940

https://www.kubernetes.org.cn/4956.html

 

關於kubernetes生產高可用集群搭建待續


免責聲明!

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



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