導航:首頁 > 程序命令 > kubadm命令

kubadm命令

發布時間:2022-09-12 23:09:16

Ⅰ yum list kubeadm --showplicates 這個命令是啥左右

列出yum源內所有的kbubeadm版本
希望可以幫助你 請採納

Ⅱ 基於linux自己初步搭建Kubernetes(k8s)集群基礎,詳細教程



k8s官方網站:https://kubernetes.io/zh/,可自行查看相關文檔說明

k8s-master:Ubuntu--192.168.152.100

k8s-node01:Ubuntu--192.168.152.101

k8s-node02:Ubuntu--192.168.152.102



全部已安裝docker,未安裝可根據官方文檔安裝:https://docs.docker.com/get-docker/

1,禁止swap分區

K8s的要求,確保禁止掉swap分區,不禁止,初始化會報錯。

在每個宿主機上執行:


2,確保時區和時間正確

時區設置


3,關閉防火牆和selinux

ubuntu 查看防火牆命令,ufw status可查看狀態,ubuntu20.04默認全部關閉,無需設置。

4,主機名和hosts設置(可選)

非必須,但是為了直觀方便管理,建議設置。

在宿主機分別設置主機名:k8s-master,k8s-node01,k8s-node02

hosts設置


1,更改docker默認驅動為systemd

為防止初始化出現一系列的錯誤,請檢查docker和kubectl驅動是否一致,否則kubectl沒法啟動造成報錯。版本不一樣,docker有些為cgroupfs,而kubectl默認驅動為systemd,所以需要更改docker驅動。

可查看自己docker驅動命令:

更改docker驅動,編輯 /etc/docker/daemon.json (沒有就新建一個),添加如下啟動項參數即可:

重啟docker

需要在每台機器上安裝以下的軟體包:

2,更新 apt 包索引並安裝使用 Kubernetes apt 倉庫所需要的包

安裝軟體包以允許apt通過HTTPS使用存儲庫,已安裝軟體的可以忽略

3,下載公開簽名秘鑰、並添加k8s庫

國外 :下載 Google Cloud 公開簽名秘鑰:

國內:可以用阿里源即可:

請注意,在命令中,使用的是Ubuntu 16.04 Xenial 版本, 是可用的最新 Kubernetes 存儲庫。所以而非20.04 的focal。


4,更新 apt 包索引,安裝 kubelet、kubeadm 和 kubectl,並鎖定其版本

鎖定版本,防止出現不兼容情況,例如,1.7.0 版本的 kubelet 可以完全兼容 1.8.0 版本的 API 伺服器,反之則不可以。


只需要在master上操作即可。


1,初始化錯誤解決(沒有報錯的可以跳過這條)

錯誤提示1:


原因:kubectl沒法啟動,journalctl -xe查看啟動錯誤信息。


解決方案:k8s建議systemd驅動,所以更改docker驅動即可,編輯 /etc/docker/daemon.json (沒有就新建一個),添加如下啟動項參數即可:

重啟docker和kubectel


錯誤提示2:


原因:初始化生產的文件,重新初始化,需要刪除即可

錯誤提示3:


解決方法:重置配置


2,初始化完成

無報錯,最後出現以下,表示初始化完成,根據提示還需要操作。


根據用戶是root或者普通用戶操作,由於大多環境不會是root用戶,我也是普通用戶,所以選擇普通用戶操作命令:

如果是root用戶,執行以下命令:

初始化完成,用最後的提示命令 kubeadm join.... 在node機器上加入集群即可。


3,主節點pod網路設置

主節點支持網路插件:https://kubernetes.io/zh/docs/concepts/cluster-administration/addons/

這里安裝Calico網路插件:https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises

Calico官網提供三種安裝方式,1)低於50個節點,2)高於50個節點,3)etcd datastore(官方不建議此方法)。

這里選擇第一種:

安裝完成後, kubectl get node 可查看節點狀態,由NotReady變成Ready則正常,需要等幾分鍾完成。


1,node加入master節點

在所有node節點機器操作,統一已安裝完成 kubelet、kubeadm 和 kubectl,用master初始化完成後最後提示命令加入,切記要用root用戶。

加入成功後,提示如下:


再次查看kubelet服務已正常啟動。


2,需注意的坑

1:加入主節點,需要 root 用戶執行詞條命令,才可以加入master主節點。

node在沒有加入主節點master之前,kubelet服務是沒法啟動的,是正常情況,會報錯如下:


原因是缺失文件,主節點master初始化 `kubeadm init`生成。

node節點是不需要初始化的,所以只需要用root用戶`kubeadm join`加入master即可生成。

2:如果加入提示某些文件已存在,如:

原因是加入過主節點,即使沒成功加入,文件也會創建,所以需要重置節點,重新加入即可,重置命令:

3,在master查看節點

加入完成後,在master節點 kubectl get node 可查看已加入的所有節點:


這里k8s集群創建完成,下一步使用可參考我的下一篇文章:k8s初步熟悉使用介紹,實踐搭建nginx集群

Ⅲ k8s 基本使用(上)

本文將介紹 k8s 中的一些最基本的命令,並輔以解釋一些基本概念來方便理解,也就是說,本文是一篇偏向實用性而非學術性的文章,如果你想提前了解一下 k8s 相關的知識的話,可以通過以下鏈接進行學習:

k8s 是經典的一對多模型,有一個主要的管理節點 master 和許多的工作節點 slaver 。當然,k8s 也可以配置多個管理節點,擁有兩個以上的管理節點被稱為 高可用 。k8s 包括了許多的組件,每個組件都是單運行在一個 docker 容器中,然後通過自己規劃的虛擬網路相互訪問。你可以通過 kubectl get pod -n kube-system 查看所有節點上的組件容器。

在管理節點中會比工作節點運行更多的 k8s 組件,我們就是靠著這些多出來的組件來對工作節點發號施令。他們都叫什麼這里就不詳細提了。反正對於」基本使用「來說,這些名字並不重要。

要想理解一個東西就要先明白它的內在理念。通俗點就是,k8s 做了什麼?為了提供更加可靠的服務,就要增加伺服器的數量,減少每個伺服器的體量來平攤負載,而越來越多的虛擬機就會帶來越來越高的運維成本。如何讓少量的運維人員就可以管理數量眾多的伺服器及其上的服務呢?這就是 k8s 做的工作。

k8s 把數量眾多的伺服器重新抽象為一個統一的資源池 ,對於運維人員來說,他們面前沒有伺服器1、伺服器2的概念,而是一個統一的資源池,增加新的伺服器對運維人員來說,只是增加自資源池的可用量。不僅如此,k8s 把所有能用的東西都抽象成了資源的概念,從而提供了一套更統一,更簡潔的管理方式。

接下來,我會把每個基本命令當做一節來進行介紹,並輔以介紹一些基本概念。本文介紹的命令涵蓋了增刪改查四方面,可參加下面表格,因為篇幅較長,我們將 create 及之後的不那麼常用的命令放在下一篇文章 k8s 基本使用(下) 里講:

接下來進入正題,首先來了解一下 k8s 中最最最常用的命令 kubectl get ,要記住,k8s 把所有的東西都抽象成了資源,而 kubectl get 就是用來查看這些資源的。最常見的資源就是 pod 。

不僅我們自己的服務是要包裝成 pod 的,就連 k8s 自己也是運行在一堆 pod 上。接下來就讓我們查看一下 k8s 的 pod :

-n 參數指定了要查看哪個命名空間下的 pod 。 k8s 所有的 pod 都被放置在 kube-system 命名空間下。

執行了 kubectl get pod -n kube-system 命令後,你就可以看到如下內容:

其中每一行就是一個資源,這里我們看到的資源是 pod 。你看到的 pod 數量可能和我的不一致,因為這個列表裡包含了 k8s 在所有節點上運行的 pod ,你加入的節點越多,那麼顯示的 pod 也就越多。我們來一列一列的看:

kubectl get 可以列出 k8s 中所有資源

這里只介紹了如何用 kubectl 獲取 pod 的列表。但是不要把 get 和 pod 綁定在一起,pod 只是 k8s 中的一種服務,你不僅可以 get pod ,還可以 get svc ( 查看服務 )、 get rs ( 查看副本控制器 )、 get deploy ( 查看部署 )等等等等,雖然說 kubectl get pod 是最常用的一個,但是如果想查看某個資源而又不知道命令是什麼, kbuectl get <資源名> 就對了。

如果你想看更多的信息,就可以指定 -o wide 參數,如下:

加上這個參數之後就可以看到資源的所在 ip 和所在節點 node 了。

記得加上 -n

-n 可以說是 kubectl get 命令使用最頻繁的參數了,在正式使用中,我們永遠不會把資源發布在默認命名空間。所以,永遠不要忘記在 get 命令後面加上 -n 。

kubectl get 命令可以列出 k8s 中的資源,而 kubectl get pod 是非常常用的查看 pod 的命令。而 -n 參數則可以指定 pod 所在的命名空間。

kubectl describe 命令可以用來查看某一資源的具體信息,他同樣可以查看所有資源的詳情, 不過最常用的還是查看 pod 的詳情 。他也同樣可以使用 -n 參數指定資源所在的命名空間。

舉個例子,我們可以用下面命令來查看剛才 pod 列表中的某個 pod,注意不要忘記把 pod 名稱修改成自己的:

然後你就可以看到很多的信息,咱們分開說,首先是基本屬性,你可以在詳細信息的開頭找到它:

基本屬性

其中幾個比較常用的,例如 Node 、 labels 和 Controlled By 。通過 Node 你可以快速定位到 pod 所處的機器,從而檢查該機器是否出現問題或宕機等。通過 labels 你可以檢索到該 pod 的大致用途及定位。而通過 Controlled By ,你可以知道該 pod 是由那種 k8s 資源創建的,然後就可以使用 kubectl get <資源名> 來繼續查找問題。例如上文 DaemonSet/kube-flannel-ds-amd64 ,就可以通過 kubectl get DaemonSet -n kube-system 來獲取上一節資源的信息。

內部鏡像信息

在中間部分你可以找到像下面一樣的 Containers 段落。該段落詳細的描述了 pod 中每個 docker 容器的信息,常用的比如 Image 欄位,當 pod 出現 ImagePullBackOff 錯誤的時候就可以查看該欄位確認拉取的什麼鏡像。其他的欄位名都很通俗,直接翻譯即可。

事件

在 describe 查看詳情的時候,最常用的信息獲取處就是這個 Event 段落了,你可以在介紹內容的末尾找到它,如下:

是的,如果你看到上面這樣,沒有任何 Events 的話,就說明該 pod 一切正常。當 pod 的狀態不是 Running 時,這里一定會有或多或少的問題,長得像下面一樣,然後你就可以通過其中的信息分析 pod 出現問題的詳細原因了:

kubectl describe <資源名> <實例名> 可以查看一個資源的詳細信息,最常用的還是比如 kubectl describe pod <pod名> -n <命名空間> 來獲取一個 pod 的基本信息。如果出現問題的話,可以在獲取到的信息的末尾看到 Event 段落,其中記錄著導致 pod 故障的原因。

如果你想查看一個 pod 的具體日誌,就可以通過 kubectl logs <pod名> 來查看。注意,這個只能查看 pod 的日誌。通過添加 -f 參數可以持續查看日誌。例如,查看 kube-system 命名空間中某個 flannel pod 的日誌,注意修改 pod 名稱:

然後就可以看到如下輸出:

如果你發現某個 pod 的服務有問題,但是狀態還是顯示 Running ,就可以使用 kubectl logs 來查看其詳細日誌。

在本篇文章里,我們了解了 k8s 的宗旨和一些基本概念,並知道了最為常用的 get 、 descibe 及 logs 命令,知道了這三條命令之後就幾乎可以從 k8s 中獲取所有常用信息了。接下來的 k8s 基本使用(下) 里,我們會更深一步,來了解 k8s 中如何創建、修改及刪除資源。

Ⅳ kubernetes— 記一次用kubeadm搭建kubernetes v1.9.0集群

目標:使用kubeadm搭建kubernetes v1.9.0集群

操作系統:Ubuntu 16.04.3

Ubuntu-001 :192.168.1.110

ubuntu-002 : 192.168.1.106

步驟總結:

1、安裝Docker CE

2、安裝kubeadm、kubectl、kubelet

3、利用kubeadm init初始化kubernetes集群

4、利用kubeadm join加入node節點到集群

具體操作步驟:

在Ubuntu 16.04安裝Docker CE (使用apt-get進行安裝)

# step 1: 安裝必要的一些系統工具  

sudo apt-get update  

sudo apt-get -y install apt-transport-httpsca-certificates curl software-properties-common  

# step 2: 安裝GPG證書  

curl -fsSLhttp://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -  

# Step 3: 寫入軟體源信息  

sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs)stable"  

# Step 4: 更新並安裝 Docker-CE  

sudo apt-get -y update  

sudo apt-get -y install docker-ce  

# 安裝指定版本的Docker-CE:  

# Step 1: 查找Docker-CE的版本:  

# apt-cache madison docker-ce  

#   docker-ce | 17.03.1~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages  

#   docker-ce | 17.03.0~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages  

# Step 2: 安裝指定版本的Docker-CE: (VERSION 例如上面的 17.03.1~ce-0~ubuntu-xenial)  

# sudo apt-get -y install docker-ce=[VERSION]  

安裝kubelet kubeadm和kubectl

由於國內google被牆,因此無法按照官方文檔操作,現添加aliyun源,可成功安裝kubelet kubeadm和kubectl。

# step 1:安裝必要的一些系統工具  

apt-get update && apt-get install -y apt-transport-https  

# step 2:安裝GPG證書  

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -  

# step 3:更新軟體源信息  

cat << EOF >/etc/apt/sources.list.d/kubernetes.list  

deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main  

EOF  

# step 4:更新並安裝kubelet kubeadm kubectl  

apt-get update  

apt-get install -y kubelet kubeadm kubectl  

# 或者安裝指定版本kubelet kubeadm kubectl  

apt-get install -y kubelet=1.9.6-00 kubeadm=1.9.6-00 kubectl=1.9.6-00  

# step 5:設置kubelet自啟動,並啟動kubelet  

systemctl enable kubelet && systemctl start kubelet  

利用kubeadm初始化kubernetes集群

如果在國內的話,需要提前准備kubernetes的各鏡像,具體參考: 在國內如何巧妙獲取kubernetes各鏡像?

root@Ubuntu-001:~# kubeadm init --kubernetes-version=v1.9.0 --pod-network-cidr=10.244.0.0/16  

[init] Using Kubernetesversion: v1.9.0  

[init] Using Authorizationmodes: [Node RBAC]  

[preflight] Runningpre-flight checks.  

         [WARNING SystemVerification]: docker version is greater thanthe most recently validated version. Docker version: 17.12.0-ce. Max validatedversion: 17.03  

         [WARNING FileExisting-crictl]: crictl not found in system path  

[preflight] Starting thekubelet service  

[certificates] Generated cacertificate and key.  

[certificates] Generatedapiserver certificate and key.  

[certificates] apiserverserving cert is signed for DNS names [ubuntu-001 kubernetes kubernetes.defaultkubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1192.168.1.110]  

[certificates] Generatedapiserver-kubelet-client certificate and key.  

[certificates] Generated sakey and public key.  

[certificates] Generatedfront-proxy-ca certificate and key.  

[certificates] Generatedfront-proxy-client certificate and key.  

[certificates] Valid certificatesand keys now exist in "/etc/kubernetes/pki"  

[kubeconfig] Wrote KubeConfigfile to disk: "admin.conf"  

[kubeconfig] Wrote KubeConfigfile to disk: "kubelet.conf"  

[kubeconfig] Wrote KubeConfigfile to disk: "controller-manager.conf"  

[kubeconfig] Wrote KubeConfigfile to disk: "scheler.conf"  

[controlplane] Wrote StaticPod manifest for component kube-apiserver to"/etc/kubernetes/manifests/kube-apiserver.yaml"  

[controlplane] Wrote StaticPod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"  

[controlplane] Wrote StaticPod manifest for component kube-scheler to"/etc/kubernetes/manifests/kube-scheler.yaml"  

[etcd] Wrote Static Podmanifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"  

[init] Waiting for thekubelet to boot up the control plane as Static Pods from directory"/etc/kubernetes/manifests".  

[init] This might take aminute or longer if the control plane images have to be pulled.  

[apiclient] All control planecomponents are healthy after 38.006067 seconds  

[uploadconfig] Storingthe configuration used in ConfigMap "kubeadm-config" in the"kube-system" Namespace  

[markmaster] Will mark nodeubuntu-001 as master by adding a label and a taint  

[markmaster] Masterubuntu-001 tainted and labelled with key/value:node-role.kubernetes.io/master=""  

[bootstraptoken] Using token:3ef896.6fe4c166c546aa89  

[bootstraptoken] ConfiguredRBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes toget long term certificate credentials  

[bootstraptoken] ConfiguredRBAC rules to allow the csrapprover controller automatically approve CSRs froma Node Bootstrap Token  

[bootstraptoken] ConfiguredRBAC rules to allow certificate rotation for all node client certificates inthe cluster  

[bootstraptoken] Creating the"cluster-info" ConfigMap in the "kube-public" namespace  

[addons] Applied essentialaddon: kube-dns  

[addons] Applied essentialaddon: kube-proxy  

Your Kubernetes master hasinitialized 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 podnetwork to the cluster.  

Run "kubectl apply -f[podnetwork].yaml" with one of the options listed at:  

 https://kubernetes.io/docs/concepts/cluster-administration/addons/  

You can now join any numberof machines by running the following on each node  

as root:  

kubeadm join --token 3ef896.6fe4c166c546aa89192.168.1.110:6443 --discovery-token-ca-cert-hashsha256:  

至此,master節點創建完畢

常見錯誤:

1、Port 2379被佔用

[preflight] Some fatal errors occurred:

         [ERROR Port-2379]: Port2379 is in use

解決方法:netstat -anp|grep 2379查看是哪個進程在佔用,2379是etcd的埠,很可能是多次執行導致。Kill掉該進程。

2、提示swap為打開狀態

[ERROR Swap]: running with swap on is not supported. Please disableswap

[preflight] If you know what you are doing, you can make a checknon-fatal with `--ignore-preflight-errors=...`

解決方法:執行swapoff -a即可

3、其他錯誤

https://kubernetes.io/docs/setup/independent/troubleshooting-kubeadm/

接下來,按照kubeadm init的輸出列印配置

對於非root用戶:

mkdir -p $HOME/.kube  

sudo cp -i /etc/kubernetes/admin.conf$HOME/.kube/config  

sudo chown $(id -u):$(id -g) $HOME/.kube/config  

root用戶:

export KUBECONFIG=/etc/kubernetes/admin.conf  

為了能夠使得pod間可以相互通信,你需要安裝pod network插件

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml  

一旦pod network安裝成功,可以執行:

kubectl get pods --all-namespaces -o wide  

利用kubeadm join加入Ubuntu-002節點到集群

Ubuntu-002節點安裝Docker、kubeadm、kubectl、kubelet,並且本地已pull了kubernetes鏡像。

根據kubeadm init最後輸出的加入集群的命令kubeadm join,將Ubuntu-002節點加入集群成為node節點

root@Ubuntu-002:~# kubeadm join --token 6aefa6.a55aba3998eda615 192.168.1.110:6443--discovery-token-ca-cert-hashsha256:  

[preflight] Runningpre-flight checks.  

         [WARNING SystemVerification]: docker version is greater thanthe most recently validated version. Docker version: 17.12.0-ce. Max validatedversion: 17.03  

         [WARNING FileExisting-crictl]: crictl not found in systempath  

[discovery] Trying to connectto API Server "192.168.1.110:6443"  

[discovery] Createdcluster-info discovery client, requesting info from"https://192.168.1.110:6443"  

[discovery] Requesting infofrom "https://192.168.1.110:6443" again to validate TLS against thepinned public key  

[discovery] Cluster infosignature and contents are valid and TLS certificate validates against pinnedroots, will use API Server "192.168.1.110:6443"  

[discovery] Successfullyestablished connection with API Server "192.168.1.110:6443"  

This node has joined thecluster:  

* Certificate signing requestwas sent to master and a response  

  was received.  

* The Kubelet was informed ofthe new secure connection details.  

Run 'kubectl get nodes'on the master to see this node join the cluster. 

node節點ubuntu-002加入集群,可以依次加入其他node節點。在master節點運行kubectl get nodes。

當然,如果想要在非master節點(node節點或者非集群遠程主機)執行kubectl命令,需要

scp root@:/etc/kubernetes/admin.conf .  

kubectl --kubeconfig ./admin.conf get nodes  

例如:

不然會出現

  將node節點ubuntu-002 從集群中刪除

1、kubectl drain ubuntu-002 --delete-local-data --force--ignore-daemonsets --kubeconfig ./admin.conf  

2、kubectl delete node ubuntu-002 --kubeconfig admin.conf  

3、kubeadm reset  

Ⅳ kubeadm集群如何平滑的升級

可以先從1.6x升到 1.7 ,再升到1.8 ;不支持 1.6以下的版本

1. 升級系統包。更新 kubectl、kubeadm、kubelet 和 kubernetes-cni 的系統包。
a. 在 Debian 上這樣完成:
sudo apt-get update
sudo apt-get upgrade

b. 在 CentOS/Fedora 上則運行:
sudo yum update

2. 重啟 kubelet

systemctl restart kubelet

3. 刪除 kube-proxy DaemonSet
雖然這個步驟自動升級了大部分組件,但當前仍需要手動刪除 kube-proxy 以使其可以使用正確的版本重建:
sudo KUBECONFIG=/etc/kubernetes/admin.conf kubectl delete daemonset kube-proxy -n kube-system

4. 執行 kubeadm 升級
警告:當引導集群時,所有傳遞給第一個 kubeadm init 的參數都必須在用於升級的 kubeadm init 命令中指定。我們計劃在 v1.8 引入這個限制。

sudo kubeadm init --skip-preflight-checks --kubernetes-version <DESIRED_VERSION>

例如,如果要升級到 1.7.0,可以運行:

sudo kubeadm init --skip-preflight-checks --kubernetes-version v1.7.0

5. 升級 CNI provider
您的 CNI provider 現在可能有它自己升級說明。檢查 addons 頁面,找到您的 CNI provider 並查看是否有必要的額外升級步驟。

參考:將 kubeadm 集群從 1.7 升級到 1.8

Ⅵ K8S安裝和創建集群終極教程(單master多worker)

本文會以 最簡單 最直接 最完整 的方式記錄kubernetes(下面統稱K8S)單master多工作節點(worker nodes)的集群步驟

首先要簡單了解一下本文的3個核心概念:

內存建議至少4G

問:如何查看主機名?

答:執行命令hostname

問:如何修改主機名?

答:永久生效的做法:執行命令vi /etc/hostname,把第一行去掉(不能注釋掉,要去掉),然後重新寫上自定義的主機名(注意命名規范),保存並重啟後生效;

臨時生效的做法:執行以下命令

問:如何查看MAC地址?

答:執行命令ip link,然後看你的第一網卡

問:如何查看proct_uuid?

答:執行命令sudo cat /sys/class/dmi/id/proct_uuid

注意:30000-32767這個埠范圍是我們創建服務的埠必須要設置的一個范圍(如果設置范圍以外的會有限制提示並創建失敗),這是K8S規定的。

另外,如果你要直接關閉防火牆可以執行

⑥必須禁用Swap

Swap total大於0,說明Swap分區是開啟的

問:如何關閉Swap?

答:編輯文件/etc/fstab,在swap行前面加上#號注釋, 保存並重啟伺服器

再次查看分區狀態,已生效

常見的容器引擎(Container runtime,簡稱runtime):

本文使用的容器引擎是Docker

安裝完成後查看版本:

當出現可能跟Docker引擎相關的奇怪異常時可以嘗試把Docker卸載干凈並重新安裝,但一定要注意鏡像、容器、卷或配置文件這些是否需要備份。

下面記錄卸載Docker引擎的步驟:

①卸載 Docker Engine、CLI 和 Containerd 包:

②主機上的映像、容器、卷或自定義配置文件不會自動刪除。刪除所有鏡像、容器和卷:

③配置文件如果有不合法的字元時會導致啟動失敗,我們需要將其刪除然後重建

此時Docker引擎已卸載干凈

官網用的是谷歌的yum源,因為國內是連不上的,所以這里替換成阿里提供的yum源

①安裝

從安裝信息中可以看到版本號是1.22

Installing:

kubeadm x86_64 1.22.4-0 kubernetes 9.3 M

kubectl x86_64 1.22.4-0 kubernetes 9.7 M

kubelet x86_64 1.22.4-0 kubernetes 20 M

②啟動



這就是一個驅動程序,注意cgroup和cgroupfs不要混淆了

引用官方的一段話

「由於 kubeadm 把 kubelet 視為一個系統服務來管理,所以對基於 kubeadm 的安裝, 我們推薦使用 systemd 驅動,不推薦 cgroupfs 驅動。」

kubeadm默認是使用systemd 驅動,而我們的Docker默認驅動是cgroupfs(docker info可以查看),所以需要將Docker的驅動改成systemd

①編輯Docker配置文件

②重啟Docker服務

再次docker info查看驅動信息已變成了systemd

工作節點(worker nodes)的最小配置就到這里了

①鏡像源參數說明

默認情況下, kubeadm 會從 k8s.gcr.io 倉庫拉取鏡像,國內是拉不了的。官方文檔明確表示允許你使用其他的 imageRepository 來代替 k8s.gcr.io。

--image-repository 你的鏡像倉庫地址

接下來我找了一些國內的鏡像源,並簡單做了下分析

綜合上述統計,我選擇阿里雲的鏡像源

②ip地址范圍參數說明

--pod-network-cidr =192.168.0.0/16

注意:如果192.168.0.0/16已經在您的網路中使用,您必須選擇一個不同的pod網路CIDR,在上面的命令中替換192.168.0.0/16。

集群初始化命令:

因為我用的是演示機器,所以這里把完整的執行信息都貼出來方便查閱,平時工作中一定要注意保護好敏感的信息(我的ip地址范圍是自定義的便於下面的功能演示,另外初次init需要下載鏡像文件,一般需要等幾分鍾)

如上所示,集群初始化成功,此時一定要注意看上面執行結果最後的那部分操作提示,我已用標明了初始化成功後還需要執行的3個步驟

注意:如果init成功後發現參數需要調整,可以執行kubeadm reset,它的作用是盡最大努力恢復kubeadm init 或者 kubeadm join所做的更改。

To start using your cluster, you need to run the following as a regular user:

翻譯:開始使用集群前,如果你是普通用戶(非root),你需要執行以下的命令:

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

翻譯:或者,如果你使用的是root,你可以執行以下命令:

(注意:export只是臨時生效,意味著每次登錄你都需要執行一次)

網路配置配的就是Pod的網路,我的網路插件選用calico

cidr就是ip地址范圍,如果您使用 pod CIDR 192.168.0.0/16,請跳到下一步。

但本文中使用的pod CIDR是192.100.0.0/16,所以我需要取消對清單中的 CALICO_IPV4POOL_CIDR 變數的注釋,並將其設置為與我選擇的 pod CIDR 相同的值。(注意一定要注意好格式,注意對齊)

可根據需求自定義清單,一般不需要的就直接跳過這步

在所有的工作節點上執行join命令(復制之前初始化成功後返回的加入集群命令到所有的工作節點執行即可)

master上查看所有節點的狀態

到這里集群已經創建完成

最後我再安裝K8S的可視化界面kubernetes-dashboard,方便我們日常使用

①下載yaml文件

②修改yaml文件,新增type和nodePort,使服務能夠被外部訪問

③安裝並查看運行情況

④新建用戶

文件創建完成後保存並apply

⑤獲取Token,用於界面登錄

⑥登錄dashboard

192.168.189.128是我的master伺服器ip,另外要注意必須使用https,並且不能使用ie內核模式

復制⑤生成的token到輸入框,點擊登錄

dashboard安裝配置完成

問:如何在查看資源情況?

答:在master上執行以下命令可查看資源情況(-o wide是顯示更詳細的信息),

①查看所有節點

②查看所有命名空間

③查看命名空間下的pod

④查看所有命名空間的pod

⑤實時查看查看命名空間下的pod運行情況

問:kubeadm join 出現異常[ERROR Port-10250]: Port 10250 is in use,如何解決?

答:這是因為你之前join失敗過了,需要先執行kubeadm reset再重新join

問:虛擬機上測試時網卡突然消失如何解決(題外問題記錄)?

答:

①確認丟失的網卡信息,ens開頭(可選步驟)

ifconfig -a

②執行以下命令解決

問:如何查看K8S版本?

答:kubectl version

問:join命令忘記或者過期了怎麼辦?

答:

生成永不過期的

生成時效24小時的

問:Pod不斷重啟並且無其它報錯信息時怎麼辦?

答:這種情況通常是因為你的集群中只有master,沒有worker節點,master的創建默認是有污點的,即不允許調度新的Pod,如果你需要(當然這並不推薦),就需要刪除 master 上的污點。刪除污點可以執行以下命令,

它應該返回以下內容。

Ⅶ Troubleshooting 故障排除 kubeadm

As with any program, you might run into an error installing or running kubeadm. This page lists some common failure scenarios and have provided steps that can help you understand and fix the problem.

對於任何項目,你可能會遇到一個錯誤安裝或運行kubeadm。這個頁面列出了一些常見的故障場景和提供可以幫助你理解和解決問題的步驟。

[TOC]

在安裝期間ebtables或一些類似的可執行文件沒有找到

If you see the following warnings while running kubeadm init

Then you may be missing ebtables, ethtool or a similar executable on your node. You can install them with the following commands:

If you notice that kubeadm init hangs after printing out the following line:

This may be caused by a number of problems. The most common are:

There are two common ways to fix the cgroup driver problem:

control plane Docker containers are crashlooping or hanging. You can check this by running docker ps and investigating each container by running docker logs.

The following could happen if Docker halts and does not remove any Kubernetes-managed containers:

A possible solution is to restart the Docker service and then re-run kubeadm reset:

一個可能的解決辦法是重新啟動 Docker 服務,然後重新運行 kubeadm reset

Inspecting the logs for docker may also be useful:
檢查``docker`日誌也可能是有用的

Right after kubeadm init there should not be any pods in these states.
在kubeadm init之後,這些狀態中不應該有任何pod。

If there are pods in one of these states right after kubeadm init, please open an issue in the kubeadm repo. coredns (or kube-dns) should be in the Pending state until you have deployed the network solution.
如果在kubeadm初始化之後有pod處於這些狀態之一,請在kubeadm repo中打開一個問題。在部署網路解決方案之前,coredns(或kube-dns)應該處於掛起狀態。

If you see Pods in the RunContainerError , CrashLoopBackOff or Error state after deploying the network solution and nothing happens to coredns (or kube-dns), it』s very likely that the Pod Network solution that you installed is somehow broken.

部署網路解決方案後,如果你看到 RunContainerError , CrashLoopBackOff or Error 狀態,什麼都沒發生coredns(或kube-dns),它很可能是你安裝的吊艙網路解決方案是破碎的。

You might have to grant it more RBAC privileges or use a newer version. Please file an issue in the Pod Network providers』 issue tracker and get the issue triaged there.

你可能需要授予它更多的RBAC特權或使用一個新版本。請在Pod網路提供商的issue tracker中的一個問題,這個問題修復。

If you install a version of Docker older than 1.12.1, remove the MountFlags=slave option when booting dockerd with systemd and restart docker. You can see the MountFlags in /usr/lib/systemd/system/docker.service. MountFlags can interfere with volumes mounted by Kubernetes, and put the Pods in CrashLoopBackOff state. The error happens when Kubernetes does not find var/run/secrets/kubernetes.io/serviceaccount files.

coredns (or kube-dns)處於掛起狀態

This is expected and part of the design.
這是預期和設計的一部分。

kubeadm is network provider-agnostic, so the admin should install the pod network solution of choice.
kubeadm is network provider-agnostic,,所以管理員應該安裝可選的pod網路解決方案。
You have to install a Pod Network before CoreDNS may be deployed fully.
你必須安裝 Pod Network , CoreDNS 才可能完全部署。

Hence the Pending state before the network is set up.
因此,網路設置之前掛起狀態

The HostPort and HostIP functionality is available depending on your Pod Network provider. Please contact the author of the Pod Network solution to find out whether HostPort and HostIP functionality are available.

主機埠和HostIP功能取決於Pod網路提供程序。請聯系Pod網路解決方案的作者,以了解是否有可用的主機埠和HostIP功能。

Calico, Canal, and Flannel CNI providers are verified to support HostPort.
經過驗證,Calico, Canal, and Flannel CNI支持HostPort。

For more information, see the CNI portmap documentation.

If your network provider does not support the portmap CNI plugin, you may need to use the NodePort feature of services or use HostNetwork=true.

如果您的網路提供商不支持portmap CNI插件,您可能需要使用服務的NodePort特性或使用HostNetwork=true

Many network add-ons do not yet enable hairpin mode which allows pods to access themselves via their Service IP. This is an issue related to CNI. Please contact the network add-on provider to get the latest status of their support for hairpin mode.
許多網路附加組件還沒有啟用允許pod通過其服務IP訪問自身的發夾模式。這是一個與CNI相關的問題。請與網路插件提供商聯系,以獲得他們支持發夾模式的最新狀態。

If you are using VirtualBox (directly or via Vagrant), you will need to ensure that hostname -i returns a routable IP address. By default the first interface is connected to a non-routable host-only network. A work around is to modify /etc/hosts , see this Vagrantfile for an example.
如果您正在使用VirtualBox(直接或通過Vagrant),則需要確保 hostname -i 返回一個可路由的IP地址。默認情況下,第一個介面連接到一個不可路由的主機網路。一種解決方法是修改 /etc/hosts ,參見這個Vagrantfile中的示例。

The following error indicates a possible certificate mismatch.

The following error might indicate that something was wrong in the pod network:

If you』re using flannel as the pod network inside Vagrant, then you will have to specify the default interface name for flannel.

如果在Vagrant中使用 flannel 作為pod網路,則必須為 flannel 指定默認介面名。

Vagrant typically assigns two interfaces to all VMs. The first, for which all hosts are assigned the IP address 10.0.2.15, is for external traffic that gets NATed.
Vagrant通常為所有vm分配兩個介面。第一種方法為所有主機分配IP地址10.0.2.15,用於指定外部流量。

This may lead to problems with flannel, which defaults to the first interface on a host. This leads to all hosts thinking they have the same public IP address. To prevent this, pass the --iface eth1 flag to flannel so that the second interface is chosen.

這可能會導致 flannel 的問題, flannel 默認是主機上的第一個介面。這導致所有主機認為它們擁有相同的公共IP地址。為了防止這種情況發生,將 —iface eth1 標志傳遞給 flannel ,以便選擇第二個介面。

In some situations kubectl logs and kubectl run commands may return with the following errors in an otherwise functional cluster:
在某些情況下,kubectl日誌和kubectl run命令可能會在功能集群中返回以下錯誤

Use ip addr show to check for this scenario instead of ifconfig because ifconfig will not display the offending alias IP address.

Alternatively an API endpoint specific to Digital Ocean allows to query for the anchor IP from the droplet:

The workaround is to tell kubelet which IP to use using --node-ip . When using Digital Ocean, it can be the public one (assigned to eth0 ) or the private one (assigned to eth1 ) should you want to use the optional private network. The KubeletExtraArgs section of the kubeadm NodeRegistrationOptions structure can be used for this.

解決方法是告訴 kubelet 使用哪個IP——node-ip。在使用Digital Ocean時,如果您想使用可選的專用網路,它可以是公共的(分配給eth0),也可以是私有的(分配給eth1)。kubeadm NodeRegistrationOptions結構中的KubeletExtraArgs部分可以用於此目的。

Then restart kubelet:

systemctl daemon-reload
systemctl restart kubelet
coredns pods have CrashLoopBackOff or Error state
If you have nodes that are running SELinux with an older version of Docker you might experience a scenario where the coredns pods are not starting. To solve that you can try one of the following options:

Upgrade to a newer version of Docker.

Disable SELinux.

Modify the coredns deployment to set allowPrivilegeEscalation to true:

kubectl -n kube-system get deployment coredns -o yaml |
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' |
kubectl apply -f -
Another cause for CoreDNS to have CrashLoopBackOff is when a CoreDNS Pod deployed in Kubernetes detects a loop. A number of workarounds are available to avoid Kubernetes trying to restart the CoreDNS Pod every time CoreDNS detects the loop and exits.

Warning: Disabling SELinux or setting allowPrivilegeEscalation to true can compromise the security of your cluster.
etcd pods restart continually
If you encounter the following error:

rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:110: decoding init error from pipe caused "read parent: connection reset by peer""
this issue appears if you run CentOS 7 with Docker 1.13.1.84. This version of Docker can prevent the kubelet from executing into the etcd container.

To work around the issue, choose one of these options:

Roll back to an earlier version of Docker, such as 1.13.1-75

yum downgrade docker-1.13.1-75.git8633870.el7.centos.x86_64 docker-client-1.13.1-75.git8633870.el7.centos.x86_64 docker-common-1.13.1-75.git8633870.el7.centos.x86_64
Install one of the more recent recommended versions, such as 18.06:

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce-18.06.1.ce-3.el7.x86_64
Not possible to pass a comma separated list of values to arguments inside a --component-extra-args flag
kubeadm init flags such as --component-extra-args allow you to pass custom arguments to a control-plane component like the kube-apiserver. However, this mechanism is limited e to the underlying type used for parsing the values (mapStringString).

If you decide to pass an argument that supports multiple, comma-separated values such as --apiserver-extra-args "enable-admission-plugins=LimitRanger,NamespaceExists" this flag will fail with flag: malformed pair, expect string=string. This happens because the list of arguments for --apiserver-extra-args expects key=value pairs and in this case NamespacesExists is considered as a key that is missing a value.

Alternatively, you can try separating the key=value pairs like so: --apiserver-extra-args "enable-admission-plugins=LimitRanger,enable-admission-plugins=NamespaceExists" but this will result in the key enable-admission-plugins only having the value of NamespaceExists.

A known workaround is to use the kubeadm configuration file.

kube-proxy scheled before node is initialized by cloud-controller-manager
In cloud provider scenarios, kube-proxy can end up being scheled on new worker nodes before the cloud-controller-manager has initialized the node addresses. This causes kube-proxy to fail to pick up the node』s IP address properly and has knock-on effects to the proxy function managing load balancers.

The following error can be seen in kube-proxy Pods:

server.go:610] Failed to retrieve node IP: host IP unknown; known addresses: []
proxier.go:340] invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP
A known solution is to patch the kube-proxy DaemonSet to allow scheling it on control-plane nodes regardless of their conditions, keeping it off of other nodes until their initial guarding conditions abate:

kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchele", "key": "node-role.kubernetes.io/master" } ] } } } }'
The tracking issue for this problem is here.

The NodeRegistration.Taints field is omitted when marshalling kubeadm configuration
Note: This issue only applies to tools that marshal kubeadm types (e.g. to a YAML configuration file). It will be fixed in kubeadm API v1beta2.

By default, kubeadm applies the role.kubernetes.io/master:NoSchele taint to control-plane nodes. If you prefer kubeadm to not taint the control-plane node, and set InitConfiguration.NodeRegistration.Taints to an empty slice, the field will be omitted when marshalling. When the field is omitted, kubeadm applies the default taint.

There are at least two workarounds:

Use the role.kubernetes.io/master:PreferNoSchele taint instead of an empty slice. Pods will get scheled on masters, unless other nodes have capacity.

Remove the taint after kubeadm init exits:

kubectl taint nodes NODE_NAME role.kubernetes.io/master:NoSchele-

Ⅷ 使用kubeadm搭建高可用的K8S集群(2022年1月親測有效)

kubeadm是官方社區推出的一個用於快速部署kubernetes集群的工具。

這個工具能通過兩條指令完成一個kubernetes集群的部署:

在開始之前,部署Kubernetes集群機器需要滿足以下幾個條件:

3.1 安裝相關包和keepalived

3.2配置master節點

master1節點配置

master2節點配置

3.3 啟動和檢查

在兩台master節點都執行

啟動後查看master1的網卡信息

4.1 安裝

4.2 配置

兩台master節點的配置均相同,配置中聲明了後端代理的兩個master節點伺服器,指定了haproxy運行的埠為16443等,因此16443埠為集群的入口

4.3 啟動和檢查

兩台master都啟動

檢查埠

Kubernetes默認CRI(容器運行時)為Docker,因此先安裝Docker。

5.1 安裝Docker

5.2 添加阿里雲YUM軟體源

5.3 安裝kubeadm,kubelet和kubectl

由於版本更新頻繁,這里指定版本號部署:

6.1 創建kubeadm配置文件

在具有vip的master上操作,這里為master1

6.2 在master1節點執行

按照提示保存以下內容,一會要使用(kubeadm init中的回顯內容):

按照提示配置環境變數,使用kubectl工具:

查看集群狀態

創建kube-flannel.yml,在master1上執行

安裝flannel網路

檢查

8.1 復制密鑰及相關文件

從master1復制密鑰及相關文件到master2

8.2 master2加入集群

執行在master1上init後輸出的join命令,需要帶上參數--control-plane表示把master控制節點加入集群(之前kubeadm init回顯內容)

檢查狀態(master1上執行)

在node1上執行

向集群添加新節點,執行在kubeadm init輸出的kubeadm join命令(之前kubeadm init回顯內容,注意不加--control-plane):

集群網路重新安裝,因為添加了新的node節點(在master1上執行)

檢查狀態(在master1上執行)

在Kubernetes集群中創建一個pod,驗證是否正常運行:

訪問地址:http://192.168.3.158:31030

Ⅸ k8s 1.14版本證書過期問題解決

說起來,都是淚,從三年前和這個問題作斗爭,證書過期和自動續期這個大問題,始終是一個心頭的傷。
現在要想到一刀切的方案,還是自己更改Kubeadm源碼,全部改成100年,最灑脫。
但,如果線上已運行了這些東東,且是10年1年證書過期的都有,那啷個弄嘛?

先用如下命令,看看k8s的哪些證書何時到期

輸出pki下的證書情況:

輸出/etc/kubernetes下的證書情況

cp -R /etc/kubernetes /etc/kubernetes$(date "+%Y%m%d")

又或者一條命令搞定
kubeadm init phase kubeconfig all
這里有個注意的細節,在使用kubeadm命令之前,它會到外網查找此K8s集群的版本信息,如果我們的機器是純企業內網,不能訪問外面,這里就會卡住。
BUT,還是可以離線進行的。
先從本集群生成一個config view類型文件。
kubeadm config view > kubeadm.conf
然後,在之後生成證書時,加上這個文件作為--config參數即可。如
kubeadm alpha phase kubeconfig scheler --config kubeadm.conf
(上面是kueadm 1.10版本的命令,新版本已從alpha轉正式命令,-h可找出來)

如果生疏了,可能看看help命令

1,仍然先備份喲,備份使得萬年船~~
cp -R /etc/kubernetes /etc/kubernetes$(date "+%Y%m%d")
2,先將要過期的證書作更名

3,生成k8s的config view,然後使用kubeadm生成新的證書對

4,依次升級完其它幾個要過期的證書,包括與etcd連接的證書對。
5,注意,有三個根證書對,是20年過期的,我沒有更新(關鍵我不清楚更新之後,會發生什麼事)。

6,根據不同版本,查看證書過期的命令還不一樣呢,最好再作個重復記錄。
查看/etc/kubernetes/pki目錄證書過期

查看/etc/kubernetes/目錄下的幾個conf里的證書過期

Ⅹ k8s常用命令

命令行 敲出的指令分為2種,

資源管理方式分類

直接使用命令去操作k8s資源,命令和參數一起出現

通過命令和配置文件去操作作k8s資源,命令還是那個命令,只不過參數都放在配置文件裡面

使用apply創建資源,

說明

在master節點執行以下命令即可刪除

還需要在work節點上執行以下命令來清空ini配置

先在主節點創建令牌

然後在需要加入集群的節點中執行令牌,注意這里的命令是通過 kubeadm token create --print-join-command 命令返回的結果

說明

記住,名稱中不能用下劃線 _ ,可以用橫行 - 第一種創建方式–命令行創建

第二種創建方式–命令行 + 配置文件
創建一個名為namespace-dev.yaml的文件,內容如下(注意大小寫,kind的頭字母必須大寫)

然後偶執行命令進行創建

需要注意的是,刪除後,當前命名空間下的pod、deployment、 container 也會一起刪掉

第一種–使用命令刪除

第二種–使用配置文件刪除

說明

獲取所有namespace的pod並監視資源變動
加上 -w 表示監視資源變動信息,此時命令行進入阻塞狀態,如果pod有變化將會馬上呈現出來;

其他參數

因為pod裡面至少要有一個容器,所以pod是和容器一起創建的,新建一個文件 pod.ymal ,內容如下

然後執行命令並指定配置文件進行創建

以下示例是為pod資源打標簽,這種方式是和pod一起創建的,新建一個配置文件 label.yaml

執行命令創建pod

適合更新label值,前提是label的key必須已存在;

刪除key為lebelKey的標簽

pod控制器有很多種,我們這里就用deployment

使用以下run命令運行一個nginx,deployment名稱為 app=run-cmd-nginx-deploy-3

通過以下命令可以看到,會自動生成一個 app=run-cmd-nginx-deploy-3 的標簽

新建一個deployment.yaml文件,內容如下

需要注意的是,一旦刪除pod控制器,此pod控制器下的所有pod和容器也會一並刪除;

默認創建的pod是只能對內訪問的,所以需要創建一個對外的訪問埠,創建一個service其實就是暴露對外的訪問埠

說明

創建好service之後,查看service信息,可以看到,暴露的埠為:30474,

新建一個service.ymal文件,內容如下

以下三種用法都可以

查詢pod控制器和pod

Endpoint是kubernetes中的一個資源對象,存儲在etcd中,用來記錄一個service對應的所有pod的訪問地址,它是根據service配置文件中selector描述產生的。

一個Service由一組Pod組成,這些Pod通過Endpoints暴露出來,Endpoints是實現實際服務的端點集合。換句話說,service和pod之間的聯系是通過endpoints實現的。

每創建一個service,k8s會自動創建一個同名的 Endpoint出來

如果是由service創建出來的endpoints,刪除後會馬上創建出一個同名的endpoint出來,如果要刪除必須先刪除service

因為每次創建一個service,k8s會自動創建一個同名的 Endpoint出來,所我們直接創建service就可以了

--help 用來查看幫助文檔,如果你不知道某個命令怎麼使用了,就可以用 --help 查詢命令的用法

explain用來查看配置文件的 資源結構,如果不知道配置文件中的資源用有哪些結構,那麼就可以使用explain命令來查看

閱讀全文

與kubadm命令相關的資料

熱點內容
我的世界網易版怎麼壓縮地圖 瀏覽:682
qq小程序雲伺服器和 瀏覽:739
方舟伺服器怎麼玩才好玩 瀏覽:557
單片機的部件 瀏覽:621
編譯原理遍的過程 瀏覽:252
python讀取json字元串 瀏覽:62
ubuntu1404安裝php 瀏覽:628
lua能編譯嗎 瀏覽:116
思仙怎麼看伺服器 瀏覽:658
php微信圖片防盜鏈 瀏覽:798
安卓1怎麼讀音 瀏覽:291
農業app怎麼開通快捷支付 瀏覽:910
pythonredisdict 瀏覽:385
如何攻擊別人網賭伺服器 瀏覽:880
隱私與應用加密的圖案密碼 瀏覽:38
陳情令王一博解壓 瀏覽:39
c編譯器使用說明 瀏覽:707
鄭州前端程序員私活有風險嗎 瀏覽:14
小型螺桿機壓縮機 瀏覽:520
成人解壓最好的方法 瀏覽:52