kubeadm是Kubernetes官方提供的用於快速部署Kubernetes集羣的工具,本篇文章使用kubeadm搭建一個單master節點的k8s集羣。html
節點部署信息node
節點主機名 | 節點IP | 節點角色 | 操做系統 |
k8s-master | 10.10.55.113 | master | centos7.6 |
k8s-node1 | 10.10.55.114 | node | centos7.6 |
節點說明linux
master:控制節點。kube-apiserver負責API服務,kube-controller-manager負責容器編排,kube-scheduler負責調度nginx
node:工做節點。kubelet 主要負責同容器運行時(好比 Docker 項目)打交道。而這個交互所依賴的,是一個稱做 CRI(Container Runtime Interface)的遠程調用接口,這個接口定義了容器運行時的各項核心操做,好比:啓動一個容器須要的全部參數git
master核心組件 | node核心組件 |
kube-apiserver | kubelet |
kube-controller-manager | |
kube-scheduler |
如下操做無特殊說明均在每一個節點執行。github
#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
RHEL / CentOS 7上的一些用戶報告了因爲iptables被繞過而致使流量路由不正確的問題。建立/etc/sysctl.d/k8s.conf文件,添加以下內容:web
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 -P FORWARD ACCEPT
因爲ipvs已經加入到了內核的主幹,因此爲kube-proxy開啓ipvs的前提須要加載如下的內核模塊:
在全部的Kubernetes節點執行如下腳本:docker
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。centos
yum install ipset
yum install ipset ipvsadm -y
Kubernetes默認的容器運行時仍然是Docker,使用的是kubelet中內置dockershim CRI實現。須要注意的是,Kubernetes 1.13最低支持的Docker版本是1.11.1,最高支持是18.06,而Docker最新版本已是18.09了,故咱們安裝時須要指定版本爲18.06.1-ceapi
#配置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
官方安裝文檔能夠參考:
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
注意這裏執行初始化用到了- -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 是管理 Kubernetes Cluster 的命令行工具,前面咱們已經在全部的節點安裝了 kubectl。Master 初始化完成後須要作一些配置工做,而後 kubectl 就能使用了。
依照 kubeadm init 輸出的最後提示,推薦用 Linux 普通用戶執行 kubectl。
#建立普通用戶並設置密碼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"}
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/
#執行如下命令將節點接入集羣 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
[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>
運行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
修改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生產高可用集羣搭建待續