環境信息
說明
1、使用kubeadm安裝集群
虛擬機信息
hostname |
memory |
cpu |
disk |
role |
node1.com |
4G |
2C |
vda20G vdb20G |
master |
node1.com |
4G |
2C |
vda20G vdb20G |
node |
其中vda為系統盤,vdb為docker storage,用於存儲容器和鏡像
配置主機名
#以下在兩個節點執行
hostnamectl set-hostname node1.com hostnamectl set-hostname node2.com
配置阿里雲k8s yum repo
#以下在兩個節點執行
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF yum update -y yum upgrade yum clean all yum makecache
安裝docker
#在兩個節點執行
yum install -y docker
配置docker-storage為deviceMapper
#在兩個節點執行
#創建pv pvcreate /dev/vdb #使用上述創建的pv創建docker-vg vgcreate docker-vg /dev/vdb #配置docker使用docker-vg作為后端存儲 echo VG=docker-vg > /etc/sysconfig/docker-storage-setup docker-storage-setup #將docker-vg的docker-pool這個lv擴展到100% lvextend -l 100%VG /dev/docker-vg/docker-pool #啟動docker並設置開機自啟 systemctl start docker systemctl enable docker
安裝其他需要的軟件
#以下在兩個節點執行
yum install -y bridge-utils
關閉防火牆、swap和selinux
#以下在兩個節點執行
systemctl stop firewalld && systemctl disable firewalld swapoff -a setenforce 0
各節點配置主機名解析
#在兩個節點執行
cat <<EOF >> /etc/hosts 172.31.2.130 node1.com 172.31.2.131 node2.com EOF
安裝kubelet kubeadm kubectl
#以下在master執行
#查看yum repo中kubelet可用的版本 yum list --showduplicates | grep kubelet
#安裝 kubelet-1.11.1 、kubeadm-1.11.1 和kubectl-1.11.1
yum install -y kubelet-1.11.1 yum install -y kubectl-1.11.1
yum install -y kubeadm-1.11.1
由於安裝kubeadm會自動安裝kubectl、kubelet,安裝kubeadm-1.11.1依賴安裝的kubectl和kubelet版本並不是1.11.1,而是最新的
(1)可以將非1.11.1的組件通過yum remove再重新安裝
(2)按照上述順序先安裝Kubectl-1.11.1和kubelet-1.11.1就沒有問題
#查看上述安裝是否是對應1.11版本
yum list installed | grep "kubernetes"
正確安裝完之后如下所示

#配置kubelet開機啟動
systemctl enable kubelet
拉取鏡像
以下在master執行
docker pull mirrorgooglecontainers/kube-apiserver-amd64:v1.11.1 docker pull mirrorgooglecontainers/pause-amd64:3.1 docker pull mirrorgooglecontainers/kube-controller-manager-amd64:v1.11.1 docker pull mirrorgooglecontainers/kube-scheduler-amd64:v1.11.1 docker pull mirrorgooglecontainers/kube-proxy-amd64:v1.11.1 docker pull mirrorgooglecontainers/etcd-amd64:3.2.18 docker pull coredns/coredns:1.1.3 docker tag mirrorgooglecontainers/kube-apiserver-amd64:v1.11.1 k8s.gcr.io/kube-apiserver-amd64:v1.11.1 docker tag mirrorgooglecontainers/pause-amd64:3.1 k8s.gcr.io/pause:3.1 docker tag mirrorgooglecontainers/kube-controller-manager-amd64:v1.11.1 k8s.gcr.io/kube-controller-manager-amd64:v1.11.1 docker tag mirrorgooglecontainers/kube-scheduler-amd64:v1.11.1 k8s.gcr.io/kube-scheduler-amd64:v1.11.1 docker tag mirrorgooglecontainers/kube-proxy-amd64:v1.11.1 k8s.gcr.io/kube-proxy-amd64:v1.11.1 docker tag mirrorgooglecontainers/etcd-amd64:3.2.18 k8s.gcr.io/etcd-amd64:3.2.18 docker tag coredns/coredns:1.1.3 k8s.gcr.io/coredns:1.1.3
以下在node執行
docker pull coredns/coredns:1.1.3 docker pull mirrorgooglecontainers/pause-amd64:3.1 docker pull mirrorgooglecontainers/kube-proxy-amd64:v1.11.1 docker tag coredns/coredns:1.1.3 k8s.gcr.io/coredns:1.1.3 docker tag mirrorgooglecontainers/pause-amd64:3.1 k8s.gcr.io/pause:3.1 docker tag mirrorgooglecontainers/kube-proxy-amd64:v1.11.1 k8s.gcr.io/kube-proxy-amd64:v1.11.1
使用kubeadm初始化集群
#此處pod-network-cidr地址范圍應與下面的flannel yaml中定義的一致
kubeadm init --kubernetes-version=v1.11.1 --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
加入計算節點到集群中
以下在需要加入集群的節點中執行
#獲取加入集群需要使用的hash值 openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' #獲取加入集群需要使用的token值 kubeadm token list
#如果上述命令沒有token,說明已過期,通過如下命令重新生成
kubeadm token create
#使用kubeadm加入集群 kubeadm join node1.com:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
此時kubectl get nodes如下,因為還沒有配置網絡插件
配置Flannel網路插件
#新建kube-flannel.yaml文件 --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: flannel rules: - apiGroups: - "" resources: - pods verbs: - get - apiGroups: - "" resources: - nodes verbs: - list - watch - apiGroups: - "" resources: - nodes/status verbs: - patch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: flannel roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: flannel subjects: - kind: ServiceAccount name: flannel namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: flannel namespace: kube-system --- kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg namespace: kube-system labels: tier: node app: flannel data: cni-conf.json: | { "name": "cbr0", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } --- apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-system labels: tier: node app: flannel spec: template: metadata: labels: tier: node app: flannel spec: hostNetwork: true nodeSelector: beta.kubernetes.io/arch: amd64 tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule serviceAccountName: flannel initContainers: - name: install-cni image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64 command: - cp args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist volumeMounts: - name: cni mountPath: /etc/cni/net.d - name: flannel-cfg mountPath: /etc/kube-flannel/ containers: - name: kube-flannel image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr - --iface=eth0 resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: true env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumeMounts: - name: run mountPath: /run - name: flannel-cfg mountPath: /etc/kube-flannel/ volumes: - name: run hostPath: path: /run - name: cni hostPath: path: /etc/cni/net.d - name: flannel-cfg configMap: name: kube-flannel-cfg
#使用kubectl創建kube-flannel ds kubectl apply -f kube-flannel.yaml
#部署完成查看flannel pod和節點的狀態
部署測試應用
#部署nginx deployment kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml #expose deployment,類型為NodePort kubectl expose deployment nginx-deployment --type=NodePort
設置master參與調度
#取消master節點的taints污點屬性
kubectl taint node node1.com node-role.kubernetes.io/master-
安裝過程中遇到的問題
1、kubectl kubelet kubeadm的版本不一致導致安裝失敗
#通過一條命令yum install -y kubectl-1.11.1 kubelet-1.11.1 kubeadm-1.11.1 報依賴問題無法安裝 #需要通過逐一使用yum進行安裝 yum install -y kubelet-1.11.1 yum install -y kubectl-1.11.1 yum install -y kubeadm-1.11.1
#逐一安裝之后,通過以下命令發現版本不是1.11.1 yum list installed | grep "kubernetes"
#將不是1.11.1版本的remove之后,重新install即可
#原因可能是yum install kubeadm-1.11.1時會附帶安裝高版本的kubelet 和 kubectl
2、flannel pod啟動失敗,CrashLoopBackOff,通過kubectl logs {pod_name}如下
I0815 00:25:37.646559 1 main.go:201] Could not find valid interface matching ens32: error looking up interface ens32: route ip+net: no such network interface E0815 00:25:37.646628 1 main.go:225] Failed to find interface to use that matches the interfaces and/or regexes provided
需要查看虛擬機的網卡名稱,如下,為eth0,並與flannel pod的yaml文件中--iface=eth0 arg保持一致
3、部署nginx后,無法通過公網ip:nodePort訪問
需要在阿里雲控制台中為對應的實例配置安全組規則:開放30000-32767端口
4、docker-storage出現問題時可以通過如下方式重置docker-storage
#重置docker-storage
rm -rf /etc/sysconfig/docker-storage rm -rf /var/lib/docker #報如下錯誤 rm: cannot remove ‘/var/lib/docker/devicemapper’: Device or resource busy rm: cannot remove ‘/var/lib/docker/containers’: Device or resource busy #通過 umount /var/lib/docker/devicemapper umount /var/lib/docker/containers #即可刪除/var/lib/docker目錄 docker-storage-setup --reset
#配置docker使用docker-vg作為后端存儲 echo VG=docker-vg > /etc/sysconfig/docker-storage-setup docker-storage-setup