K8s 常見問題及解決方案
- 我已經通過k8s官方提供的解決方案安裝的docker,並且docker可以成功運行。 啟動minikube的時候出現的問題
xiaoqu@k8s2:~$ sudo minikube start --driver=none
[sudo] password for xiaoqu:
Sorry, try again.
[sudo] password for xiaoqu:
😄 minikube v1.12.1 on Ubuntu 16.04
✨ Using the none driver based on user configuration
💣 Sorry, Kubernetes 1.18.3 requires conntrack to be installed in root's path
Sorry, Kubernetes 1.18.3 requires conntrack to be installed in root's path
之前在另一台虛擬機上安裝minikube 就沒有出現這個問題。
解決方法:
安裝conntract
,之后在此嘗試啟動minikube。
sudo apt-get install conntract -y
參考 :
https://github.com/kubernetes/minikube/issues/7179
- docker 的Cgroup driver 改為 systemd
# (Install Docker CE)
## Set up the repository:
### Install packages to allow apt to use a repository over HTTPS
apt-get update && apt-get install -y \
apt-transport-https ca-certificates curl software-properties-common gnupg2
# Add Docker’s official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
# Add the Docker apt repository:
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
apt-get update && apt-get install -y \
containerd.io=1.2.13-2 \
docker-ce=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) \
docker-ce-cli=5:19.03.11~3-0~ubuntu-$(lsb_release -cs)
重點來了
# Set up the Docker daemon
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"], ## 這里改為了systemd
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# Restart Docker
systemctl daemon-reload
systemctl restart docker
# enable start on boot
sudo systemctl enable docker
參考:
https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/
sudo kubeadm init 出現下列錯誤
[ERROR Swap]: running with swap on is not supported. Please disable swap.
解決方法:
sudo swapoff -a
永久關閉:
vim /etc/fstab
注釋掉下邊這行
# /dev/mapper/k8s1--vg-swap_1 none swap sw 0 0
參考
How do I disable swap? - Ask Ubuntu
https://github.com/kubernetes/kubeadm/issues/610
問題:
sudo kubelet
] failed to run Kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"
解決
目前也沒有找到正確的姿勢,唯一的方式就是重新安裝docker 和 kubectl
問題: k8s 集群搭好了 kubectl get nodes
role是空的,如何指定節點的role
root@k8s2:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s1 Ready <none> 14h v1.18.6
k8s2 Ready master 15h v1.18.6
答案:
暫時沒記錄 。
問題 如何查看K8s集群的版本號
答案:我是用kube admin 構建的k8s集群,用minikube構建的可能會不一樣
kubeadm version
root@k8s2:~/k8s# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.6", GitCommit:"dff82dc0de47299ab66c83c626e08b245ab19037", GitTreeState:"clean", BuildDate:"2020-07-15T16:56:34Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
這里是1.18.6
如何刪除加入集群中的節點
下線節點
root@k8s2:~# kubectl drain k8s1 --ignore-daemonsets --delete-local-data
node/k8s1 already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-bw8mn
node/k8s1 drained
確認下線
root@k8s2:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s1 Ready,SchedulingDisabled <none> 23h v1.18.6
k8s2 Ready master 23h v1.18.6
刪除節點
root@k8s2:~# kubectl delete node k8s1
node "k8s1" deleted
root@k8s2:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s2 Ready master 23h v1.18.6
root@k8s2:~#
刪除成功
kubeadm init 如何指定pod的網絡段
sudo kubeadm init --pod-network-cidr=192.168.0.0/16
參考: https://docs.projectcalico.org/getting-started/kubernetes/quickstart
如何配置K8s集群的calico網絡
前提
基於kubeadm init 指定的pod網絡段。
kubeadm init 之后的coreDNS狀態
root@k8s2:~/k8s# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-66bff467f8-l4lq5 0/1 Pending 0 65s
kube-system coredns-66bff467f8-mqpxc 0/1 Pending 0 65s
kube-system etcd-k8s2 1/1 Running 0 75s
kube-system kube-apiserver-k8s2 1/1 Running 0 75s
kube-system kube-controller-manager-k8s2 1/1 Running 0 75s
kube-system kube-proxy-5twv5 1/1 Running 0 65s
kube-system kube-scheduler-k8s2 1/1 Running 0 75s
下載calico網絡配置文件
wget -P ~/k8s/ https://docs.projectcalico.org/v3.8/manifests/calico.yaml
編輯calico.yaml
修改默認網絡段和你在kubeadm init指定的一致
vim calico.yaml /192.168 可快速定位
> - name: CALICO_IPV4POOL_CIDR
> value: "10.10.0.0/16"
安裝插件
kubectl apply -f calico.yaml
查看狀態
啟動比較慢需要等大約1-2min
watch kubectl get pods --all-namespaces
root@k8s2:~/k8s# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-75d555c48-x87bq 1/1 Running 0 12m
kube-system calico-node-g2rhd 1/1 Running 0 12m
kube-system coredns-66bff467f8-l4lq5 1/1 Running 0 13m
kube-system coredns-66bff467f8-mqpxc 1/1 Running 0 13m
kube-system etcd-k8s2 1/1 Running 0 13m
kube-system kube-apiserver-k8s2 1/1 Running 0 13m
kube-system kube-controller-manager-k8s2 1/1 Running 0 13m
kube-system kube-proxy-5twv5 1/1 Running 0 13m
kube-system kube-scheduler-k8s2 1/1 Running 0 13m
安裝成功。
參考:
https://www.jianshu.com/p/3de558d8b57a
k8s 的服務如何讓外網去訪問
背景:
我在把ubuntu 裝在了兩個不同的虛擬機里,網絡都是橋接的。這兩個組成了k8s的集群,想讓集群里部署的服務被我的真實的物理機訪問到。
解決方式有四種:
- hostNetwork: true 直接暴露 pod在部署pod的節點上,然后通過節點的ip加端口去訪問。
yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-kube
spec:
hostNetwork: true
containers:
- name: hello-kube
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: "hello-kube"
- hostPort 直接定義Pod網絡的方式,通過宿主機和pod之間的端口映射,類似直接起docker 然后做端口映射。
yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-kube
spec:
containers:
- name: hello-kube
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
hostPort: 8081
env:
- name: MESSAGE
value: "hello-kube-host-port"
- nodePort 定義網絡方式
NodePort在kubenretes里是一個廣泛應用的服務暴露方式。
Kubernetes中的service默認情況下都是使用的ClusterIP這種類型,這樣的service會產生一個ClusterIP,這個IP只能在集群內部訪問,要想讓外部能夠直接訪問service,需要將service type修改為 nodePort。
apiVersion: v1
kind: Pod
metadata:
name: hello-kube
labels:
name: hello-kube
spec:
containers:
- name: hello-kube
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: "hello-kube-node-port"
---
apiVersion: v1
kind: Service
metadata:
name: hello-kube
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30001 # 只能在區間 30000-32767
selector:
name: hello-kube
- LoadBalancer 只能在service上定義
yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-kube
labels:
name: hello-kube
spec:
containers:
- name: hello-kube
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: "hello-kube-load-balancer"
---
apiVersion: v1
kind: Service
metadata:
name: hello-kube
spec:
type: LoadBalancer
ports:
- port: 8080
selector:
name: hello-kube
- ingress
創建service 和pod 的yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-kube
labels:
name: hello-kube
spec:
containers:
- name: hello-kube
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: "hello-kube-load-balancer"
---
apiVersion: v1
kind: Service
metadata:
name: hello-kube
spec:
ports:
- port: 8080
selector:
name: hello-kube
service 狀態
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kube ClusterIP 10.111.142.96 <none> 8080/TCP 4s
集群重啟之后無法使用kubelet
The connection to the server 192.168.2.121:6443 was refused - did you specify the right host or port?
1. sudo -i
2. swapoff -a
3. exit
4. strace -eopenat kubectl version
手動關掉 swapoff 在master 節點
nodePort 不生效
設置service type為 nodePort, 理論上能在集群中任意ip均可訪問,但是只能在部署pod的節點訪問
暫時沒找到能在kubeadm 上建立的集群的解決方案。
port, nodePort, targetPort 分別是指什么?
port 是在k8s集群內部暴露的端口,其他sevice/pod可以通過這個端口開訪問
nodePort: 也就是在k8s集群的node上暴露的端口,供外界訪問。宿主機的端口。
targetPort: pod 本身自己暴露的端口,也就是k8s內部和外界訪問的流量最終都會到這里。
configMap的值變了為什么 pod引用的內容沒變?
congMapYaml
apiVersion: v1
kind: ConfigMap
metadata:
name: hello-kube-config
labels:
name: hello
data:
MESSAGE: "message"
name: "hello"
service with deployments Yaml
apiVersion: v1
kind: Service
metadata:
name: hello-kube-d
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kube-d
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kube-d
spec:
replicas: 1
selector:
matchLabels:
app: hello-kube-d
template:
metadata:
labels:
app: hello-kube-d
spec:
containers:
- name: hello-kube-d
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
valueFrom:
configMapKeyRef:
name: hello-kube-config
key: MESSAGE # 這里引用的是configMap的值
答案:
當configMap作為 environment variable 加載到pod中,當configMap對應的key發生改變時,需要重啟pod才能生效。
當confgiMap 作為卷mount到系統中,變更將自動生效,但是有延遲,在下次ttl檢查之前不會生效,之后才會成效。
集群無法部署pod
解決方法: 需要安裝網絡插件,安裝完成之后 coreDNS的pod才會啟起來,之后才可以用。