K8s 常见问题及解决方案

Posted qulianqing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8s 常见问题及解决方案相关的知识,希望对你有一定的参考价值。

K8s 常见问题及解决方案

  1. 我已经通过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


  1. 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

参考

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的集群,想让集群里部署的服务被我的真实的物理机访问到。

解决方式有四种:

  1. 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"

技术图片

  1. 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"

技术图片

  1. 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
  1. 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
  1. 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才会启起来,之后才可以用。









以上是关于K8s 常见问题及解决方案的主要内容,如果未能解决你的问题,请参考以下文章

解决flannel下k8s pod及容器无法跨主机互通问题

彻底搞懂 K8S Pod Pending 故障原因及解决方案

经典k8s日常巡检及排错指南

经典k8s日常巡检及排错指南

部署k8s集群及报错完美解决方案

K8S规划方案及操作步骤