1. 程式人生 > >還不會K8S嗎?先從kubeadm開始吧

還不會K8S嗎?先從kubeadm開始吧

[TOC] kubeadm是Kubernetes官方提供的用於快速安裝Kubernetes叢集的工具,伴隨Kubernetes每個版本的釋出都會同步更新,kubeadm會對叢集配置方面的一些實踐做調整,通過實驗kubeadm可以學習到Kubernetes官方在叢集配置上一些新的最佳實踐。 在Kubernetes的文件Creating a single master cluster with kubeadm中已經給出了目前kubeadm的主要特性已經處於beta狀態了,在2018年將進入GA狀態,說明kubeadm離可以在生產環境中使用的距離越來越近了。 下面我將介紹一下kubeadm的安裝,比起k8s的二進位制安裝方式,kubeadm的安裝門檻較低,更容易上手。 ## 1. 準備工作 ### 1.1 機器準備 準備三臺Centos7.x虛擬機器,具體配置如下: | IP | Role | CPU | Memory | Hostname | | --------------- | ------ | ----- | ------ | -------- | | 192.168.199.231 | master | >= 2C | >= 2G | master | | 192.168.199.232 | worker | >= 2C | >= 2G | node1 | | 192.168.199.233 | worker | >= 2C | >= 2G | node1 | > IP 根據你自己宿主機機器網段決定。 ### 1.2 系統配置 #### 1.2.1 主機名及域名解析 ``` # 192.168.199.231上執行 hostnamectl set-hostname master # 192.168.199.232上執行 hostnamectl set-hostname node1 # 192.168.199.233上執行 hostnamectl set-hostname node2 # 192.168.199.231、192.168.199.232、192.168.199.233三臺都執行 cat <>/etc/hosts 192.168.199.231 master 192.168.199.232 node1 192.168.199.233 node2 EOF ``` > 設定完後,相互ping一下看看網路是否通。如:ping node1 #### 1.2.2 免密登入 設定 master 可以無密碼登入所有節點的 root 賬戶: ``` ## 第一步:在master節點執行,一路回車到底 ssh-keygen -t rsa ## 第二步:在master節點執行以下三句,然後分別輸入對應機器登入密碼 ssh-copy-id root@master ssh-copy-id root@node1 ssh-copy-id root@node2 ``` #### 1.2.3 配置yum源 注意:所有虛擬機器都需要執行下面的操作 配置阿里軟體源(base和epel): ``` mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo ``` > 最後一句記得回車,配置完過後,可通過命令: > > yum repolist > > 來檢視是否配置成功。如果出現如下資訊則表示成功: > > * base: mirrors.aliyun.com > * extras: mirrors.aliyun.com > * updates: mirrors.aliyun.com 配置國內Kubernetes源: ``` cat < /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 ``` 配置docker源: ``` wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo ``` 執行清理和更新: ``` yum clean all && yum makecache && yum update -y # 第一次需要比較久的時間,去喝杯水休息休息 ``` #### 1.2.4 安裝必要依賴包 在三臺機器上執行命令: ``` yum install -y epel-release yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget /usr/sbin/modprobe ip_vs # 這一句記得回車 ``` > ipvs 依賴 ipset > > ntp 保證各機器系統時間同步; #### 1.2.5 關閉防火牆、SELinux、Swap分割槽 注意:所有虛擬機器都需要執行下面的操作 關閉防火牆: ``` systemctl stop firewalld && systemctl disable firewalld && iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT ``` 關閉SELinux: ``` setenforce 0 sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config ``` 關閉Swap分割槽: ``` swapoff -a sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab ``` #### 1.2.6 配置核心引數 注意:所有虛擬機器都需要執行下面的操作 將橋接的IPv4流量傳遞到iptables的鏈,swappiness引數調整: ``` cat < /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward=1 net.ipv4.tcp_tw_recycle=0 vm.swappiness=0 # 禁止使用 swap 空間,只有當系統 OOM 時才允許使用它 vm.overcommit_memory=1 # 不檢查實體記憶體是否夠用 vm.panic_on_oom=0 # 開啟 OOM EOF modprobe ip_vs_rr modprobe br_netfilter sysctl --system # 記得回車 ``` ## 2. 安裝Docker ### 2.1 安裝 Kubernetes從1.6開始使用CRI(Container Runtime Interface)容器執行時介面。預設的容器執行時仍然是Docker,使用的是kubelet中內建dockershim CRI實現。 檢視版本: ``` # 檢視docker版本 yum list docker-ce.x86_64 --showduplicates | sort -r # 檢視docker cli版本 yum list docker-ce-cli.x86_64 --showduplicates |sort -r ``` Kubernetes 1.15已經針對Docker的1.13.1, 17.03, 17.06, 17.09, 18.06,18.09等版本做了驗證,需要注意Kubernetes 1.15最低支援的Docker版本是1.13.1。 我們這裡在各節點安裝docker的19.03.9版本。 ``` # 安裝docker、docker-cli yum install -y docker-ce-19.03.9-3.el7 docker-ce-cli-19.03.9-3.el7 # 開機啟動 && 啟動docker systemctl enable docker && systemctl start docker # 檢視版本 docker --version ``` 安裝docker還可以通過指令碼,詳情見:[https://leisure.wang/procedural-framework/docker/112.html](https://leisure.wang/procedural-framework/docker/112.html) ### 2.2 配置映象加速 ``` # 第一步:建立目錄(不存在則建立) mkdir -p /etc/docker # 第二步:建立並配置daemon.json檔案 cat > /etc/docker/daemon.json <
kubeadm.yml ``` 針對kubeadm.yml檔案做修改,新增修改處有4個,如下注釋位置,做相應修改即可: ``` apiVersion: kubeadm.k8s.io/v1beta2 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.199.231 # 修改項,更改為master節點IP bindPort: 6443 nodeRegistration: criSocket: /var/run/dockershim.sock name: master taints: - effect: NoSchedule key: node-role.kubernetes.io/master --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta2 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controlPlaneEndpoint: "" # 新增項 controllerManager: {} dns: type: CoreDNS etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers # 修改項,修改為阿里雲映象倉庫 kind: ClusterConfiguration kubernetesVersion: v1.18.0 networking: dnsDomain: cluster.local podSubnet: "10.244.0.0/16" # 新增項,配置Flannel的預設網段 serviceSubnet: 10.96.0.0/12 scheduler: {} --- # 新增項start:開啟IPVS模式 apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration featureGates: SupportIPVSProxyMode: true mode: ipvs # 新增項end:開啟IPVS模式 ``` 配置修改好後,將配置檔案複製到node1、node2備用: ``` scp kubeadm.yml root@node1:/root scp kubeadm.yml root@node2:/root ``` 檢視和拉取映象: ``` # 檢視所需映象列表 kubeadm config images list --config kubeadm.yml # 拉取映象 (所有機器都執行) kubeadm config images pull --config kubeadm.yml # 執行完畢後,通過命令就可以看到映象了: docker images ``` ### 3.3 使用kubeadm 配置master 節點 注意:在master執行下面的操作 #### 3.3.1 安裝 kubernetes 主節點 執行以下命令初始化主節點,該命令指定了初始化時需要使用的配置檔案,其中新增 --experimental-upload-certs 引數可以在後續執行加入節點時自動分發證書檔案。追加的 tee kubeadm-init.log 用以輸出日誌。 ``` # 初始化命令 kubeadm init --config=kubeadm.yml --upload-certs | tee kubeadm-init.log # 成功則返回如下資訊: 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 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 192.168.199.231:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:d65d8f7646c8503c40d622e29ff4ec74ce3aac5b83f87d2950d2301d6a1faf5c ``` node1、node2想要加入叢集,需要執行上一步返回結果中的命令: ``` kubeadm join 192.168.199.231:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:d65d8f7646c8503c40d622e29ff4ec74ce3aac5b83f87d2950d2301d6a1faf5c ``` >
--token:加入叢集的token > > --discovery-token-ca-cert-hash:發現token證書hash 此時還無法通過命令kubectl get nodes檢視節點資訊,需要等下面的配置。 如果忘記了加入叢集的命令怎麼辦呢?通過下面兩個方法獲取token和discovery-token-ca-cert-hash,然後按照上面的命令的格式拼接起來即可。 獲取Token,可以在 Master 上輸入以下命令檢視: ``` kubeadm token list ``` 預設情況下 Token 過期是時間是24小時,如果 Token 過期以後,可以輸入以下命令,生成新的 Token: ``` kubeadm token create ``` 獲取discovery-token-ca-cert-hash 的方法,在 Master 執行以下命令檢視: ``` openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>
/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' ``` 注意:如果安裝 kubernetes 版本和下載的映象版本不統一則會出現 timed out waiting for the condition 錯誤。中途失敗或是想修改配置可以使用 kubeadm reset 命令重置配置,再做初始化操作即可。 #### 3.3.2 配置 kubectl 執行初始化叢集時候輸出結果中的命令: ``` mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # 非root使用者執行 sudo chown $(id -u):$(id -g) $HOME/.kube/config ``` 驗證是否成功: ``` # 命令 kubectl get nodes # 結果 NAME STATUS ROLES AGE VERSION master NotReady master 18m v1.18.0 node1 NotReady 14m v1.18.0 node2 NotReady 14m v1.18.0 ``` 至此主機誒單配置完成。 #### 3.3.3 kubeadm init執行過程 - init:指定版本進行初始化操作 - preflight:初始化前的檢查和下載所需要的 Docker 映象檔案 - kubelet-start:生成 kubelet 的配置檔案 var/lib/kubelet/config.yaml,沒有這個檔案 kubelet 無法啟動,所以初始化之前的 kubelet 實際上啟動不會成功 - certificates:生成 Kubernetes 使用的證書,存放在 /etc/kubernetes/pki 目錄中 - kubeconfig:生成 KubeConfig 檔案,存放在 /etc/kubernetes 目錄中,元件之間通訊需要使用對應檔案 - control-plane:使用 /etc/kubernetes/manifest 目錄下的 YAML 檔案,安裝 Master 元件 - etcd:使用 /etc/kubernetes/manifest/etcd.yaml 安裝 Etcd 服務 - wait-control-plane:等待 control-plan 部署的 Master 元件啟動 - apiclient:檢查 Master 元件服務狀態。 - uploadconfig:更新配置 - kubelet:使用 configMap 配置 kubelet - patchnode:更新 CNI 資訊到 Node 上,通過註釋的方式記錄 - mark-control-plane:為當前節點打標籤,打了角色 Master,和不可排程標籤,這樣預設就不會使用 Master 節點來執行 Pod - bootstrap-token:生成 token 記錄下來,後邊使用 kubeadm join 往叢集中新增節點時會用到 - addons:安裝附加元件 CoreDNS 和 kube-proxy ### 3.4 使用kubeadm配置 worker 節點 #### 3.4.1 將worker加入到叢集 將 worker節點加入到叢集中很簡單,上一步也做了介紹,只需要執行init返回結果中的命令: ``` kubeadm join 192.168.199.231:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:d65d8f7646c8503c40d622e29ff4ec74ce3aac5b83f87d2950d2301d6a1faf5c ``` #### 3.4.2 驗證是否成功 在master節點上執行: ``` # 命令 kubectl get cs,nodes # 結果 NAME STATUS MESSAGE ERROR componentstatus/scheduler Healthy ok componentstatus/controller-manager Healthy ok componentstatus/etcd-0 Healthy {"health":"true"} NAME STATUS ROLES AGE VERSION node/master NotReady master 84m v1.18.0 node/node1 NotReady 80m v1.18.0 node/node2 NotReady 79m v1.18.0 ``` 如果 worker節點加入 master 時配置有問題可以在 worker節點上使用 kubeadm reset 重置配置再使用 kubeadm join 命令重新加入即可。希望在 master 節點刪除 node ,可以使用 kubeadm delete nodes 刪除。 #### 3.4.3 檢視 pod 狀態 ``` # 在master上執行 kubectl get pod -n kube-system -o wide # 結果 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES coredns-7ff77c879f-k94rw 0/1 Pending 0 86m coredns-7ff77c879f-whhdf 0/1 Pending 0 86m etcd-master 1/1 Running 0 86m 192.168.199.231 master kube-apiserver-master 1/1 Running 0 86m 192.168.199.231 master kube-controller-manager-master 1/1 Running 0 86m 192.168.199.231 master kube-proxy-8jvj5 1/1 Running 1 86m 192.168.199.231 master kube-proxy-hm8cx 1/1 Running 1 82m 192.168.199.232 node1 kube-proxy-psnc9 1/1 Running 1 82m 192.168.199.233 node2 kube-scheduler-master 1/1 Running 0 86m 192.168.199.231 master ``` 由此可以看出 coredns 尚未執行,此時我們還需要安裝網路外掛。 ### 3.5 配置網路 Kubernetes 中可選的 CNI 外掛如下: - Flannel - Calico - Canal - Weave #### 3.5.1 安裝flannel網路 ``` # 下載kube-flannel.yml檔案,如果無法下載請在附件中獲取。 curl -O https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 安裝 kubectl apply -f kube-flannel.yml ``` #### 3.5.2 配置網絡卡名稱(可選) 如果Node有多個網絡卡的話,參考flannel issues 39701,目前需要在kube-flannel.yml中使用–iface引數指定叢集主機內網網絡卡的名稱,否則可能會出現dns無法解析。需要將kube-flannel.yml下載到本地,flanneld啟動引數加上–iface=,網絡卡名稱可通過ip address命令獲取,格式為ensXX ``` # 部分內容 ...... containers: - name: kube-flannel image: quay.io/coreos/flannel:v0.11.0-amd64 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr - --iface=ens32 ...... ``` #### 3.5.3 檢視Pod狀態 使用kubectl get pod –all-namespaces -o wide確保所有的Pod都處於Running狀態: ``` # 命令 watch kubectl get pod --all-namespaces -o wide # 結果(需要等待所有狀態為Running,時間可能需要3-5分鐘) NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system coredns-7ff77c879f-k94rw 1/1 Running 0 126m 10.244.0.3 master kube-system coredns-7ff77c879f-whhdf 1/1 Running 0 126m 10.244.0.2 master kube-system etcd-master 1/1 Running 0 126m 192.168.199.231 master kube-system kube-apiserver-master 1/1 Running 0 126m 192.168.199.231 master kube-system kube-controller-manager-master 1/1 Running 0 126m 192.168.199.231 master kube-system kube-flannel-ds-amd64-6rcjk 1/1 Running 0 15m 192.168.199.231 master kube-system kube-flannel-ds-amd64-n464m 1/1 Running 0 15m 192.168.199.232 node1 kube-system kube-flannel-ds-amd64-rlghv 1/1 Running 0 15m 192.168.199.233 node2 kube-system kube-proxy-8jvj5 1/1 Running 1 126m 192.168.199.231 master kube-system kube-proxy-hm8cx 1/1 Running 1 122m 192.168.199.232 node1 kube-system kube-proxy-psnc9 1/1 Running 1 121m 192.168.199.233 node2 kube-system kube-scheduler-master 1/1 Running 0 126m 192.168.199.231 master ``` **至此基本環節已經部署完畢,如果沒有問題,就可以展開k8s的學習之旅了。** #### 3.5.4 問題處理(可選) ##### 3.5.4.1 解決 ImagePullBackOff 在使用 watch kubectl get pods --all-namespaces 命令觀察 Pods 狀態時如果出現 ImagePullBackOff 無法 Running 的情況,請嘗試使用如下步驟處理: - Master 中刪除 Nodes:kubectl delete nodes - worker中重置配置:kubeadm reset - worker重啟計算機:reboot - worker重新加入叢集:kubeadm join ##### 3.5.4.2 Master節點參與工作負載 出於安全原因,您的群集不會在主伺服器上安排pod。如果您希望能夠在主伺服器上安排pod,例如對於用於開發的單機Kubernetes叢集,可以執行以下命令: ``` # 所有主伺服器都安排 pod kubectl taint nodes --all node-role.kubernetes.io/master- # 指定節點 master 伺服器都安排 pod kubectl taint nodes node-role.kubernetes.io/master- 如:kubectl taint nodes master node-role.kubernetes.io/master- ``` ### 3.6 驗證叢集DNS是否可用 #### 3.6.1 新建檔案my-nginx.yaml ``` apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: app: my-nginx replicas: 2 template: metadata: labels: app: my-nginx spec: containers: - name: my-nginx image: nginx:1.7.9 ports: - containerPort: 80 ``` #### 3.6.2 建立Deployment並生成my-nginx服務 ``` # 建立Deployment kubectl create -f my-nginx.yaml # 檢視Deployment kubectl get deploy # 生成服務 kubectl expose deploy my-nginx # 檢視服務 kubectl get services(或 kubectl get svc) # 結果 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 3h2m my-nginx ClusterIP 10.110.206.225 80/TCP 7m34s ``` #### 3.6.3 建立dnsutils-ds.yml檔案 建立另一個 Pod,檢視 /etc/resolv.conf 是否包含 kubelet 配置的 --cluster-dns 和 --cluster-domain,是否能夠**將服務 my-nginx 解析到對應的 Cluster IP 10.110.206.225**上 ``` apiVersion: v1 kind: Service metadata: name: dnsutils-ds labels: app: dnsutils-ds spec: type: NodePort selector: app: dnsutils-ds ports: - name: http port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: dnsutils-ds labels: addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: app: dnsutils-ds template: metadata: labels: app: dnsutils-ds spec: containers: - name: my-dnsutils image: tutum/dnsutils:latest command: - sleep - "3600" ports: - containerPort: 80 ``` #### 3.6.4 建立pod dnsutils-ds ``` kubectl create -f dnsutils-ds.yml ``` #### 3.6.5 檢視pod節點 ``` # 命令 kubectl get pods # 結果 NAME READY STATUS RESTARTS AGE curl 0/1 CrashLoopBackOff 13 46m dnsutils-ds-2xgtq 1/1 Running 0 103s dnsutils-ds-dvzjm 1/1 Running 0 103s dnsutils-ds-xtsvz 1/1 Running 0 103s my-nginx-5c7d476867-sqpjv 1/1 Running 0 19m my-nginx-5c7d476867-vv57z 1/1 Running 0 19m ``` #### 3.6.6 開始驗證DNS ``` # 命令 kubectl exec dnsutils-ds-2xgtq -- nslookup my-nginx # 結果 Server: 10.96.0.10 Address: 10.96.0.10#53 Name: my-nginx.default.svc.cluster.local Address: 10.110.206.225 ``` 從結果看Address: 10.110.206.225已經成功了。 另外,解析外部域名時,需要以 . 結尾: ``` # 命令 kubectl exec dnsutils-ds-2xgtq -- nslookup leisure.wang. # 結果 Server: 10.96.0.10 Address: 10.96.0.10#53 Non-authoritative answer: Name: leisure.wang Address: 121.36.158.21 ``` ### 3.7 從叢集中刪除Node 如果需要從叢集中移除node2這個Node執行下面的命令: 在master節點上執行: ``` kubectl drain node2 --delete-local-data --force --ignore-daemonsets kubectl delete node node2 ``` 在 Node 被刪除,需要重啟所有 kubeadm 安裝狀態: ``` kubeadm reset # 如果要完全刪除,請執行下面的清理命令 ifconfig cni0 down ip link delete cni0 ifconfig flannel.1 down ip link delete flannel.1 rm -rf /var/lib/cni/ ``` ### 3.8 解決apiserver訪問時匿名使用者禁用問題 瀏覽器訪問 kube-apiserver 的安全埠 6443 時,提示: ``` { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"", "reason": "Forbidden", "details": { }, "code": 403 } ``` 對於正式環境,需要建立一個使用者並授權,在上面二進位制二進位制安裝裡介紹過,多少還是煩了點。 對於學習環境,我們不需要那麼麻煩,不就是匿名使用者被禁用了嗎,直接給匿名使用者授權就可以了。 解決辦法:繫結一個cluster-admin的許可權 ``` kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous ``` ## 4. 部署whoami whoami 是一個簡單的HTTP docker服務,用於列印容器ID 在 Master 執行部署 Whoami: ``` kubectl create deployment whoami --image=idoall/whoami ``` 檢視 Whoami 部署狀態: ``` kubectl get deployments ``` 檢視 Whoami 的部署資訊: ``` kubectl describe deployment whoami ``` 檢視 Whoami 的pod資訊: ``` kubectl describe pod whoami ``` 為 Whoami 擴充套件埠;建立一個可以通過網際網路訪問的 Whoami 容器: ``` kubectl create service nodeport whoami --tcp=80:80 ``` [本文由https://leisure.wang/整理提供] 上面的命令將在主機上為 Whoami 部署建立面向公眾的服務。 由於這是一個節點埠部署,因此 kubernetes 會將此服務分配給32000+範圍內的主機上的埠。 檢視當前的服務狀態: ``` # 命令 kubectl get svc,pods -o wide # 結果 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/dnsutils-ds NodePort 10.97.94.13 80:30157/TCP 37m app=dnsutils-ds service/kubernetes ClusterIP 10.96.0.1 443/TCP 3h45m service/my-nginx ClusterIP 10.110.206.225 80/TCP 51m app=my-nginx service/whoami NodePort 10.108.27.255 80:32729/TCP 29s app=whoami NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/curl 0/1 CrashLoopBackOff 20 82m 10.244.1.2 node1 pod/dnsutils-ds-2xgtq 1/1 Running 0 37m 10.244.1.4 node1 pod/dnsutils-ds-dvzjm 1/1 Running 0 37m 10.244.0.4 master pod/dnsutils-ds-xtsvz 1/1 Running 0 37m 10.244.2.3 node2 pod/my-nginx-5c7d476867-sqpjv 1/1 Running 0 55m 10.244.1.3 node1 pod/my-nginx-5c7d476867-vv57z 1/1 Running 0 55m 10.244.2.2 node2 pod/whoami-7976c8ddf6-9lbcp 1/1 Running 0 5m13s 10.244.2.4 node2 ``` 上面的服務可以看到 Whoami 執行在 32729 埠。 測試 Whoami 服務是否執行正常: ``` # 命令 curl node1:32729 # 結果 [mshk.top]I'm whoami-7976c8ddf6-9lbcp ``` 擴充套件部署應用: ``` kubectl scale --replicas=3 deployment/whoami ``` 檢視擴充套件後的結果,可以看到 Whoami 在 master、node1、node2上面都有部署 ClusterIP 模式會提供一個叢集內部的虛擬IP(與Pod不在同一網段),以供叢集內部的 Pod 之間通訊使用。 刪除 Whoami 部署: ``` kubectl delete deployment whoami kubectl delete service whoami ``` ## 5. 部署Dashboard Kubernetes Dashboard 是 Kubernetes 叢集的 Web UI,用於管理叢集。 ### 5.1 安裝 注:在master節點上進行如下操作 #### 5.1.0 下載配置檔案 由於網路原因,可能無法下載,無法下載則請直接使用5.1.1檔案內容 ``` wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml ``` > 如果下載成功,請參照5.1.1做如下修改: > > 1. 修改映象地址為阿里雲 > 2. 修改型別為 NodePort 訪問(無type則新增) > 3. 設定埠號為 30001 #### 5.1.1 建立檔案kubernetes-dashboard.yaml ``` apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-certs namespace: kube-system type: Opaque --- apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: kubernetes-dashboard-minimal namespace: kube-system rules: - apiGroups: [""] resources: ["secrets"] verbs: ["create"] - apiGroups: [""] resources: ["configmaps"] verbs: ["create"] - apiGroups: [""] resources: ["secrets"] resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"] verbs: ["get", "update", "delete"] - apiGroups: [""] resources: ["configmaps"] resourceNames: ["kubernetes-dashboard-settings"] verbs: ["get", "update"] - apiGroups: [""] resources: ["services"] resourceNames: ["heapster"] verbs: ["proxy"] - apiGroups: [""] resources: ["services/proxy"] resourceNames: ["heapster", "http:heapster:", "https:heapster:"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard-minimal namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kube-system --- kind: Deployment apiVersion: apps/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system spec: replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: kubernetes-dashboard template: metadata: labels: k8s-app: kubernetes-dashboard spec: containers: - name: kubernetes-dashboard image: registry.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1 # 修改映象地址為阿里雲 ports: - containerPort: 8443 protocol: TCP args: - --auto-generate-certificates volumeMounts: - name: kubernetes-dashboard-certs mountPath: /certs - mountPath: /tmp name: tmp-volume livenessProbe: httpGet: scheme: HTTPS path: / port: 8443 initialDelaySeconds: 30 timeoutSeconds: 30 volumes: - name: kubernetes-dashboard-certs secret: secretName: kubernetes-dashboard-certs - name: tmp-volume emptyDir: {} serviceAccountName: kubernetes-dashboard tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule --- kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system spec: type: NodePort # 修改型別為 NodePort 訪問(無type則新增) ports: - port: 443 targetPort: 8443 nodePort: 30001 # 設定埠號為 30001 selector: k8s-app: kubernetes-dashboard ``` #### 5.1.2 部署 ``` kubectl create -f kubernetes-dashboard.yaml ``` #### 5.1.3 檢視 ``` kubectl -n kube-system get pods kubectl -n kube-system get service kubernetes-dashboard kubectl -n kube-system describe service kubernetes-dashboard ``` ### 5.2 訪問 需要使用 NodeIP:30001(如:https://192.168.199.231:30001/) 訪問 Dashboard,因為證書原因除火狐瀏覽器外其它瀏覽器無法直接開啟頁面。 作為學習,暫時可以不用在意這些細節。訪問後,在火狐裡點選高階>接受風險並繼續。 此時將會看到“Kubernetes 儀表板”。 ### 5.3 登入 #### 5.3.1 kubeconfig方式 該config檔案位置一般是 ~/.kube/config(Master節點),只要將該檔案下載到本地機器上,登入的時候選擇它就行了。 #### 5.3.2 令牌方式 建立訪問Dashboard的token,需要建立一個 Admin 使用者並授予 Admin 角色繫結,使用下面的 yaml檔案 建立 admin 使用者並賦予管理員許可權,然後可以通過 Token 訪問 kubernetes。 建立 kubernetes-dashboard-admin.yaml 檔案: ``` apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard labels: k8s-app: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kube-system ``` 執行部署: ``` kubectl apply -f kubernetes-dashboard-admin.yaml ``` 獲取secret中的token值: ``` kubectl get secret -o wide --all-namespaces | grep kubernetes-dashboard-token # 記得替換成你自己的secret資源名 kubectl -n kube-system describe secret kubernetes-dashboard-token-bsjtr ``` 也可以通過 jsonpath 直接獲取 token: ``` kubectl -n kube-system get secret kubernetes-dashboard-token-bsjtr -o jsonpath={.data.token}|base64 -d ``` 也可以使用下面的命令,直接獲取 kubernetes-dashboard-token 的值,然後直接列印輸出: ``` k8tokenvalue=`kubectl get secret -o wide --all-namespaces | grep kubernetes-dashboard-token | awk '{print $2}'`;kubectl -n kube-system get secret $k8tokenvalue -o jsonpath={.data.token}|base64 -d | awk '{print $1}' ``` 注意:下面的獲取token值的方式和上面三種方式選擇一種即可。 您還可以通過kubectl create clusterrolebinding的方式來授予 Dashboard 服務 Admin 管理員許可權: ``` kubectl create serviceaccount dashboard-admin -n kube-system kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}') ``` 登入成功後就能看到後臺頁面了: ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_0.png) ## 6. Weave Scope 監控叢集 建立 Kubernetes 叢集並部署容器化應用只是第一步。一旦叢集執行起來,我們需要確保一起正常,所有必要元件就位並各司其職,有足夠的資源滿足應用的需求。Kubernetes 是一個複雜系統,運維團隊需要有一套工具幫助他們獲知叢集的實時狀態,併為故障排查提供及時和準確的資料支援。 ### 6.1 安裝 Weave Scope 是 Docker 和 Kubernetes 視覺化監控工具。Scope 提供了至上而下的叢集基礎設施和應用的完整檢視,使用者可以輕鬆對分散式的容器化應用進行實時監控和問題診斷。 在 K8s 叢集中安裝 Scope 的方法很簡單,使用下面的命令: ``` # 命令 kubectl apply -f "https://cloud.weave.works/k8s/scope.yaml?k8s-version=$(kubectl version | base64 | tr -d '\n')&k8s-service-type=NodePort" # 結果 service-type=NodePort" namespace/weave created serviceaccount/weave-scope created clusterrole.rbac.authorization.k8s.io/weave-scope created clusterrolebinding.rbac.authorization.k8s.io/weave-scope created deployment.apps/weave-scope-app created service/weave-scope-app created deployment.apps/weave-scope-cluster-agent created daemonset.apps/weave-scope-agent created ``` 部署成功後有如下元件: ``` # 命令 kubectl get pod -n weave # 結果 NAME READY STATUS RESTARTS AGE weave-scope-agent-2t7z2 0/1 ContainerCreating 0 60s weave-scope-agent-ll9r9 0/1 ContainerCreating 0 60s weave-scope-agent-qzp2b 0/1 ContainerCreating 0 60s weave-scope-app-bc7444d59-lznk8 0/1 ContainerCreating 0 62s weave-scope-cluster-agent-7944c858c9-ms7mz 0/1 ContainerCreating 0 61s # 命令 kubectl get svc -n weave # 結果 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE weave-scope-app NodePort 10.108.61.84 80:30286/TCP 3m9s # 命令 kubectl get deploy -n weave # 結果 NAME READY UP-TO-DATE AVAILABLE AGE weave-scope-app 1/1 1 1 4m19s weave-scope-cluster-agent 1/1 1 1 4m18s ``` - DaemonSet weave-scope-agent,叢集每個節點上都會執行的 scope agent 程式,負責收集資料。 - Deployment weave-scope-app,scope 應用,從 agent 獲取資料,通過 Web UI 展示並與使用者互動。 - Service weave-scope-app,預設是 ClusterIP 型別,我們已經在上面的命令中添加了引數k8s-service-type=NodePort修改為 NodePort。 ### 6.2 使用Scope 瀏覽器訪問http://MASTER_IP:30286/(埠可在上一步檢視命令中獲得),cope 預設顯示當前所有的 Controller(Deployment、DaemonSet 等)。 ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_1.png) #### 6.2.1 拓撲結構 Scope 會自動構建應用和叢集的邏輯拓撲。比如點選頂部 Pods,會顯示所有 Pod 以及 Pod 之間的依賴關係。 ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_2.png) 點選 Hosts,會顯示各個節點之間的關係,可以在 Scope 中檢視資源的 CPU 和記憶體使用情況。 ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_3.png) ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_4.png) #### 6.2.2 線上操作 Scope 還提供了便捷的線上操作功能,比如選中某個 Host,點選 >_ 按鈕可以直接在瀏覽器中開啟節點的命令列終端: ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_5.png) 點選 Deployment 的 + 可以執行 Scale Up 操作: ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_6.png) 可以檢視 Pod 的日誌: ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_7.png) 可以 attach、restart、stop 容器,以及直接在 Scope 中排查問題: ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_8.png) #### 6.2.3 強大的搜尋功能 Scope 支援關鍵字搜尋和定位資源。 ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_9.png) 還可以進行條件搜尋,比如查詢和定位 MEMORY > 1M 的 Containers。 ![](https://itoak.gitee.io/blog-articles/docker/imges/k8s_10.png) Weave Scope 介面極其友好,操作簡潔流暢,更多功能留給大家去探索。 官方文件:[https://www.weave.works/docs/scope/latest/installing/#k8s](#k8s) ## 寫在最後 通過kubeadm安裝k8s叢集環境的介紹就到這裡了,書寫安裝過程難免出現不足的地方,如果出了問題,需要讀者多多思考。由於國內網路的原因,文件中所需要的大部分配置檔案都已經貼了出來,讀者只需要根據自己的機器環境做相應的修改即可。通過kubeadm安裝k8s叢集環境,相對於二進位制的安裝方式來說,還是比較簡單的,需要多多實踐,才能出真知。我是[東方雨傾](https://leisure.wang/),感謝大家的支援,謝謝! ## 附件 連結:https://pan.baidu.com/s/1qWdZ_CclTxm2ybE4h8dziA 提取碼:ruo5 原文地址:[https://leisure.wang/procedural-framework/docker/513.html](https://leisure.wang/procedural-framework/docker/5