Kubernetes(k8s)快速开始

一、Kubernetes介绍

官网:https://kubernetes.io/zh/docs/home/
非官方参考 https://kubernetes.feisky.xyz/

Kubernetes 是一个开源容器编排引擎,用于容器化应用的自动化部署、扩展和管理。该项目托管在 CNCF。

在这里插入图片描述

1. 关于CNCF

开源社区云原生计算基金会(Cloud Native Computing Foundation,简称CNCF)

为了统一云计算接口和相关标准,2015 年 7 月隶属于 Linux 基金会的云原生计算基金会(CNCF)应运而生。

谈到 CNCF,首先它是一个非营利组织,致力于通过技术优势和用户价值创造一套新的通用容器技术,推动本土云计算和服务的发展。CNCF 关注于容器如何管理而不是如何创建。

2. Kubernetes重要概念介绍

K8s - Kubernetes重要概念介绍(Cluster、Master、Node、Pod、Controller、Service、Namespace)
参考URL: https://www.hangge.com/blog/cache/detail_2428.html

Cluster

  • Cluster(集群) 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。
  • 最简单的 Cluster 可以只有一台主机(它既是 Mater 也是 Node)

Master

  • Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。
  • Master 运行 Linux 操作系统,可以是物理机或者虚拟机。
  • 为了实现高可用,可以运行多个 Master。

master节点上运行着master组件,包括api server(提供k8s集群控制restful api的核心组件),scheduler(监听新建pod副本信息,并通过调度算法为该pod选择一个最合适的node),controller manager,etcd(数据存储中心,key-value数据库,存储着集群中的所有对象和状态)

Node

  • Node 的职责是运行容器应用。
  • Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。
  • Node 运行在 Linux 操作系统,可以是物理机或者是虚拟机。

Pod

  • Pod是kubernetes的最小工作单元。
  • 每个pod可以包含一个或者多个容器。Pod中的容器会作为一个整体被Master调度到一个Node上运行。
  • kubernetes 以Pod为最小单位进行调度、扩展、共享资源、管理生命周期;pod中的所有容器都共享一个网络namespace,所有的容器可以共享存储。

Controller

  • kubernetes通常不会直接去创建pod,而是通过Controller去管理pod的,Controller中定义了Pod的部署特性,比如有几个副本、什么样的Node上运行等。
  • 为了满足不同的业务场景,kubernetes提供了多种Controller,包括Deployment、ReplicaSet、DeamonSet、StatefuleSet、Job等。

Deployment :是最常用的的Controller,deployment可以管理pod的多个副本,并确保pod按照预期的状态来运行。

ReplicaSet : 实现了pod的多副本管理。使用Deployment时会自动创建Replicaset。

DeamonSet: 用于每个Node最多只能运行一个Pod副本的场景。

StatefuleSet:能够保证Pod的每个副本在整个生命周期中名称是不变的,而其它Controller是提供这个功能。当某个Pod发生故障需要删除并且重新启动时,Pod的名称会发生变化,同时StatefuleSet会保证副本按照固定的顺序启动、更新或者删除。

Service

pod的ip不是固定的,是根据所在宿主机的docker0网卡生成的,每次重启,更新,调度等情况IP都会变,那pod与pod之间需要互相调用,肯定不能用ip的,因为地址不是固定的, 如何能保障pod之前访问的可靠性,由此就衍生出Service的概念。

Deployment 可以部署多个副本,每个Pod都有自己的Ip,那么外界如何访问这些副本呢?Kubernetes Service 定义了外界访问一组特定Pod的方式。Service 有自己的IP和端口,Service为pod提供了负载均衡。

K8s运行容器Pod与访问容器Pod这两项任务分别由Controller和Service执行。

Namespace

大多数的Kubernetes中的集群默认会有一个叫default的namespace。实际上,应该是3个:

default:你的service和app默认被创建于此。
kube-system:kubernetes系统组件使用。
kube-public:公共资源使用。但实际上现在并不常用。

3. kubernetes之StatefulSet详解

kubernetes之StatefulSet详解
参考URL: https://blog.51cto.com/newfly/2140004

RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL、MongoDB集群等。

StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。

在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。

除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:

$(podname).(headless server name)   
FQDN: $(podname).(headless server name).namespace.svc.cluster.local

为什么需要 headless service 无头服务?

在用Deployment时,每一个Pod名称是没有顺序的,是随机字符串,因此是Pod名称是无序的,但是在statefulset中要求必须是有序 ,每一个pod不能被随意取代,pod重建后pod名称还是一样的。而pod IP是变化的,所以是以Pod名称来识别。pod名称是pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称 。

headless service 是将service的发布文件中的clusterip=none ,不让其获取clusterip , DNS解析的时候直接走pod。
比如场景:有时候我们创建的服务不想走 负载均衡,想直接通过 pod-ip 链接后端。

为什么需要volumeClaimTemplate?

对于有状态的副本集都会用到持久存储,对于分布式系统来讲,它的最大特点是数据是不一样的,所以各个节点不能使用同一存储卷,每个节点有自已的专用存储,但是如果在Deployment中的Pod template里定义的存储卷,是所有副本集共用一个存储卷,数据是相同的,因为是基于模板来的 ,而statefulset中每个Pod都要自已的专有存储卷,所以statefulset的存储卷就不能再用Pod模板来创建了,于是statefulSet使用volumeClaimTemplate,称为卷申请模板,它会为每个Pod生成不同的pvc,并绑定pv, 从而实现各pod有专用存储。这就是为什么要用volumeClaimTemplate的原因。

3. kubernetes: headless service

[推荐-写的比较清晰,有举例]kubernetes: headless service
参考URL: https://blog.csdn.net/textdemo123/article/details/102954489

在微服务相关场景 如果需要直通pod的时候 我们就可以使用headless service 绕过 k8s的转发机制,直接访问pod了。

三、k8s常用命令

查看类命令

查看k8s拥有的命名空间

kubectl get namespace

获取节点相应服务的信息:
kubectl get nodes
查看pod相关信息
kubectl get pods
查看指定namespace的pod信息
kubectl get pods -n namespace
按selector名来查找pod
kubectl get pod --selector name=redis
查看集群所有的pod信息

kubectl get pods -A

查看pods所在的运行节点
kubectl get pods -o wide
查看pods定义的详细信息
kubectl get pods -o yaml
查看运行的pod的环境变量
kubectl exec pod名 env
查看指定pod的日志
kubectl logs podname
滚动查看指定pod的日志
kubectl logs -f podname
查看service相关信息

kubectl get services

查看deployment相关信息
kubectl get deployment
查看指定pod的详细信息
kubectl describe pods-dasdeqwew2312-g6q8c
查看deployment历史修订版本
kubectl rollout history deployment/nginx-deployment

kubeadm命令

kubeadm init 启动一个 Kubernetes 主节点;
kubeadm join 启动一个 Kubernetes 工作节点并且将其加入到集群;
kubeadm upgrade 更新一个 Kubernetes 集群到新版本;
kubeadm config 如果使用 v1.7.x 或者更低版本的 kubeadm 初始化集群,您需要对集群做一些配置以便使用 kubeadm upgrade 命令;
kubeadm token 管理 kubeadm join 使用的令牌;
kubeadm reset 还原 kubeadm init 或者 kubeadm join 对主机所做的任何更改;
kubeadm version 打印 kubeadm 版本;
kubeadm alpha 预览一组可用的新功能以便从社区搜集反馈。

主节点相关操作

更改配置文件,重新加载
systemctl daemon-reload
启动master相关组件
systemctl start kube-apiserver/kube-controller-manager/ube-scheduler/etcd.service
停止master相关组件
systemctl stop kube-apiserver/kube-controller-manager/ube-scheduler/etcd.service
重启master相关组件
systemctl restart kube-apiserver/kube-controller-manager/ube-scheduler/etcd.service
查看master相关组件状态
systemctl status kube-apiserver/kube-controller-manager/ube-scheduler/etcd.service
查看各组件信息
kubectl get componentstatuses
查看kubelet进程启动参数
ps -ef | grep kubelet
查看日志:
journalctl -u kubelet -f
查看集群信息
kubectl cluster-info
查看各组件信息
kubectl -s http://localhost:8080 get componentstatuses

工作节点相关操作

启动worker端相关组件
systemctl start kube-proxy/docker/kubelet
停止worker端相关组件
systemctl stop kube-proxy/docker/kubelet
重启worker端相关组件
systemctl restart kube-proxy/docker/kubelet
查看worker端相关组件状态
systemctl status kube-proxy/docker/kubelet

节点相关操作

设为node为不可调度状态:
kubectl cordon node1
解除node不可调度状态
kubectl uncordon node1
将pod赶到其他节点:
kubectl drain node1
master运行pod
kubectl taint nodes master.k8s node-role.kubernetes.io/master-
master不运行pod
kubectl taint nodes master.k8s node-role.kubernetes.io/master=:NoSchedule

操作类命令

创建资源
kubectl create -f xx.yaml
重建资源
kubectl replace -f xx.yaml [–force]
删除资源
kubectl delete -f xx.yaml
删除指定pod
kubectl delete pod podname
删除指定rc
kubectl delete rc rcname
删除指定service
kubectl delete service servicename
删除所有pod
kubectl delete pod --all
导出所有configmap
kubectl get configmap -n kube-system -o wide -o yaml > configmap.yaml
进入pod
kubectl exec -it redis-master-1033017107-q47hh /bin/sh
增加lable值
kubectl label pod redis-master-1033017107-q47hh role=master
修改lable值
kubectl label pod redis-master-1033017107-q47hh role=backend --overwrite
更新资源
kubectl patch pod rc-nginx-2-kpiqt -p ‘{“metadata”:{“labels”:{“app”:“nginx-3”}}}’

升级类命令

指定资源副本数量
kubectl scale rc nginx --replicas=5
版本升级
kubectl rolling-update redis-master --image=redis-master:2.0
版本回滚
kubectl rolling-update redis-master --image=redis-master:1.0 --rollback
实时观察滚动升级状态
kubectl rollout status deployment/nginx-deployment

四、Kubernetes一键部署利器:kubeadm

官方文档:https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm/
官方Creating a single control-plane cluster with kubeadm:
参考URL: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
Kubernetes官方集群部署工具kubeadm原理解析
参考URL: https://blog.csdn.net/m2l0zgssvc7r69efdtj/article/details/79752981
Kubernetes一键部署利器:kubeadm
参考URL: https://studygolang.com/articles/18186?fr=sidebar

根据所处环境的不同,Kubernetes集群的安装部署有多种不同的方式。如果是在公有云上还好,一般都会提供相应的安装方案。如果是自行搭建私有环境,可选的安装方案则不尽相同,有时可能需要从零一步步开始,这个过程很容易出错,这往往使人感觉耗时耗力,望而却步。
kubeadm作为Kubernetes官方提供的集群部署管理工具,采用“一键式”指令进行集群的快速初始化和安装,极大地简化了部署过程,消除了集群安装的痛点。虽然kubeadm目前还不能用于生产,但社区一直在完善kubeadm的功能和稳定性。

kubeadm帮助您引导符合最佳实践的最小可行Kubernetes集群。

在环境节点符合其基本要求的前提下,kubeadm只需要两条基本命令便可以快捷的将一套集群部署起来。这两条命令分别是:

  • kubeadm init:初始化集群并启动master相关组件,在计划用做master的节点上执行
  • kubeadm join:将节点加入上述集群,在计划用做node的节点上执行

1. k8s by kubeadm 环境搭建

k8s by kubeadm 国内网络环境搭建指南
参考URL: https://github.com/nanmu42/k8s-by-kubeadm

1) 环境介绍

系统类型IProlecpumemoryhostname
CentOS 7.4.1708192.168.13.100master22Gmaster.localdomain
CentOS 7.4.1708192.168.13.101master11Gnode1.localdomain
CentOS 7.4.1708192.168.13.102master11Gnode2.localdomain
  1. Centos7修改IP地址
  cd  /etc/sysconfig/network-scripts/
  vi ifcfg-ens33

使用ls命令,列出该目录下的文件。其中**“ifcfg-ens33”**的文件,为我们需要修改的网络配置文件。

我们需要修改BOOTPROTO="static"也就是将dhcp改为static,
修改ONBOOT=“yes” 意思是将网卡设置 为开机启用,

同时在文字下方添加
IPADDR=192.168.13.100 #静态IP
GATEWAY=192.168.13.1 #默认网关
NETMASK=255.255.255.0 #子网掩码
DNS1=192.168.13.1 #DNS 配置
DNS2=8.8.8.8 #谷歌地址

使用service network restart命令,重启网络服务。

查看我们改动后的效果

因为现在是Centos7所以我们使用新的命令,我们输入ip addr进行查看。

ip addr
  1. centos7关闭防火墙

ystemctl status firewalld.service 查看防火墙状态

执行后可以看到绿色字样标注的“active(running)”,说明防火墙是开启状态

systemctl stop firewalld.service 关闭运行的防火墙 

关闭后,使用命令systemctl status firewalld.service
查看防火墙状态
可以看到,disavtive(dead)的字样,说明防火墙已经关闭

前面的方法,一旦重启操作系统,防火墙就自动开启了,该怎么设置才能永久关闭防火墙呢?

输入命令:systemctl disable firewalld.service,禁止防火墙服务器

2) 先决条件

  • 一个或更多运行Ubuntu 16.04+/CentOS 7/Debian 9,2 GB以上内存,2核以上CPU的实例;
  • 实例之间有网络联通;
  • 确保每个实例有唯一的hostname, MAC address以及product_uuid(这个条件一般都能满足,经过测试,克隆的虚拟机,这个值也不同):

验证Mac地址和product_uuid是否唯一。
Kubernetes要求集群中所有机器具有不同的Mac地址、产品uuid、Hostname。

# UUID
cat /sys/class/dmi/id/product_uuid

# Mac地址
ip link

# Hostname
cat /etc/hostname
  1. hostname
    k8s会使用实例的hostname作为节点名称,因此有必要为每个实例取一个描述性较好的名称。

实例的hostname需要满足DNS-1123规范(https://tools.ietf.org/html/rfc1123):

字符集:数字、小写字母、.、-
以小写字母开头和结尾
正则表达式为:

[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*

k8s master节点,修改hostname方式如下:

# 将 master.localdomain 换为合适的值

echo "master.localdomain" > /etc/hostname 
echo "127.0.0.1   master.localdomain" >> /etc/hosts
echo "::1   master.localdomain" >> /etc/hosts

不重启的情况下使修改生效

sysctl kernel.hostname=master.localdomain

或k8s node 节点

echo "node1.localdomain" > /etc/hostname 
echo "127.0.0.1   node1.localdomain" >> /etc/hosts
echo "::1   node1.localdomain" >> /etc/hosts

不重启的情况下使修改生效
sysctl kernel.hostname=node1.localdomain
  1. 禁用Swap
    kubelet要求宿主实例的交换空间(Swap)禁用以正常工作。
# 查看实例的swap设备
# 如果没有输出,说明没有启用swap,可略过余下步骤
cat /proc/swaps

#(1)临时关闭swap分区, 重启失效;
swapoff -a

#(2)永久关闭swap分区( 下面命令会用#注掉swap配置 )

sed -ri 's/.*swap.*/#&/' /etc/fstab

kubelet为什么关闭swap
kubernetes的想法是将实例紧密包装到尽可能接近100%。 所有的部署应该与CPU /内存限制固定在一起。 所以如果调度程序发送一个pod到一台机器,它不应该使用交换。 设计者不想交换,因为它会减慢速度。

所以关闭swap主要是为了性能考虑。

3) 配置K8S的yum源

cat <<EOF > /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

4) 安装 kubelet、kubeadm、kubectl

安装kubernets组件并启动kubernets

master节点安装
yum install docker-ce kubelet kubeadm kubectl 
node节点安装
yum install docker-ce kubelet kubeadm 

5) k8s-master节点执行kubeadm init

接下来执行 init

需要注意几点:

  1. 网卡设置
    kubeadm init操作会自动发现master节点的网卡设备,并且将其设置成默认网关。如果我们想使用不同的网络接口,可以使用 --apiserver-advertise-address= 参数来设置

    –apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。

  2. 注意一点是创建集群(init)时要增加 --pod-network-cidr 10.244.0.0/16 参数;网段根据需要自己指定,如果不使用 --pod-network-cidr 参数,则 flannel pod 启动后会出现 failed to register network: failed to acquire lease: node “xxxxxx” pod cidr not assigned 错误

    –pod-network-cidr 指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对 --pod-network-cidr 有自己的要求,这里设置为 10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个  CIDR。在后面的实践中我们会切换到其他网络方案,比如 Canal。

[root@master ~]# kubeadm init  --apiserver-advertise-address=192.168.13.100  --pod-network-cidr=10.244.0.0/16
W0111 08:11:09.700783   16440 version.go:101] could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable-1.txt": Get https://dl.k8s.io/release/stable-1.txt: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
W0111 08:11:09.700849   16440 version.go:102] falling back to the local client version: v1.17.0
W0111 08:11:09.701973   16440 validation.go:28] Cannot validate kubelet config - no validator is available
W0111 08:11:09.701982   16440 validation.go:28] Cannot validate kube-proxy config - no validator is available
[init] Using Kubernetes version: v1.17.0
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [master.localdomain kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.13.100]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [master.localdomain localhost] and IPs [192.168.13.100 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [master.localdomain localhost] and IPs [192.168.13.100 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0111 08:11:15.143326   16440 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0111 08:11:15.144934   16440 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 30.006147 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.17" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node master.localdomain as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node master.localdomain as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: ofqnzh.cmvpb2ovcgvjlxtl
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

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.13.100:6443 --token ofqnzh.cmvpb2ovcgvjlxtl \
    --discovery-token-ca-cert-hash sha256:0d63f591e8be1a4bbe12fbc32e18020cdb114203bfca7aa21b3f5f6e02b36c74 
[root@master ~]# 

6) k8s-node节点执行kubeadm join

如下直接复制init master节点的后台给你返回的命令:

[root@node1 ~]# kubeadm join 192.168.13.100:6443 --token pnw91c.3x591drl18spswp9   --discovery-token-ca-cert-hash sha256:d33e6987b9b1a2d494ab83c8ac391e4f488693462d4a8e000f0e0eeede296eb8

W0110 23:31:34.728580    5741 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

[root@node1 ~]# 

验证是否成功,
回到 master 服务器,可以看到 node1.localdomain 成功加入 master.localdomain

[root@master ~]# kubectl get nodes
NAME                 STATUS     ROLES    AGE     VERSION
master.localdomain   NotReady   master   18h     v1.17.0
node1.localdomain    NotReady   <none>   2m53s   v1.17.0
[root@master ~]# 

kubectl get pod -n kube-system -o wide
查看 pod 状态

默认token的有效期为24小时,重新生成token

默认token的有效期为24小时,当过期之后,该token就不可用了。
产生token:
kubeadm token create
oapcal.mlearjiaijljtyeq
取ca证书sha256编码hash值:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed ‘s/^.* //’
8832ca46fa644aa8d4864119430985875f27f29bc68dd86797e0b0fa4db60fb4

kubeadm join 192.168.1.130:6443 --token oapcal.mlearjiaijljtyeq --discovery-token-ca-cert-hash sha256:8832ca46fa644aa8d4864119430985875f27f29bc68dd86797e0b0fa4db60fb4

2. 安装遇到问题整理

  1. [ERROR FileContent–proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
    执行kubeadmin join报错。

解决方法:
echo “1” >/proc/sys/net/bridge/bridge-nf-call-iptables

  1. The connection to the server localhost:8080 was refused - did you specify the right host or port?
    原因:kubenetes master没有与本机绑定,集群初始化的时候没有设置

解决办法:
配置环境变量

echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

立即生效

如果没有admin.conf,说明你没有执行kubeadm init,要先执行这个命令,进行master服务的初始化。

  1. [WARNING IsDockerSystemdCheck]: detected “cgroupfs” as the Docker cgroup driver. The recommended driver is “systemd”. Please follow the guide at https://kubernetes.io/docs/setup/cri/···
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

mkdir -p /etc/systemd/system/docker.service.d

# Restart Docker
systemctl daemon-reload
systemctl restart docker
  1. [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-apiserver:v1.17.0: output: Error response from daemon: Get https://k8s.gcr.io/v2/: dial tcp 64.233.188.82:443: connect: connection timed out
    kubeadm首先会查看本机是否存在相应的docker镜像 如果有就直接启动本机的镜像如果没有就会从https://k8s.gcr.io仓库中下载相关镜像.

ImagePullBackOff 一般都是因为镜像拉不下来,很大可能是因为镜像被墙。

解决方法:
kubeadm 默认下载的镜像都是在 gcr.io 上的,国内的网络环境不能访问,我们可以先下下来,然后自己打tag。

# 查看 kubeadm 会用到的镜像
kubeadm config images list

[root@master ~]# kubeadm config images list
W0110 03:28:32.837311    7561 version.go:101] could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable-1.txt": Get https://dl.k8s.io/release/stable-1.txt: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
W0110 03:28:32.838496    7561 version.go:102] falling back to the local client version: v1.17.0
W0110 03:28:32.838882    7561 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0110 03:28:32.838904    7561 validation.go:28] Cannot validate kubelet config - no validator is available
k8s.gcr.io/kube-apiserver:v1.17.0
k8s.gcr.io/kube-controller-manager:v1.17.0
k8s.gcr.io/kube-scheduler:v1.17.0
k8s.gcr.io/kube-proxy:v1.17.0
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.5

拉取镜像,给镜像打tag

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.17.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.17.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.17.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.17.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.5


镜像重新打tag
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.17.0  k8s.gcr.io/kube-apiserver:v1.17.0

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.17.0  k8s.gcr.io/kube-controller-manager:v1.17.0

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.17.0  k8s.gcr.io/kube-scheduler:v1.17.0

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.17.0   k8s.gcr.io/kube-proxy:v1.17.0

docker tag  registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1   k8s.gcr.io/pause:3.1

docker tag  registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0  k8s.gcr.io/etcd:3.4.3-0

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.5  k8s.gcr.io/coredns:1.6.5
  1. docker报错“net/http: TLS handshake timeout”的解决方法
    为了永久性保留更改,您可以修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值。
    添加完docker镜像仓库后,需要重启docker
    [root@master ~]# systemctl daemon-reload
    [root@master ~]# systemctl restart docker
    systemctl restart docker.service

  2. kubeadmin join加入节点报错: x509: certificate has expired or is not yet valid的解决
    计入

可能是由于时间不同步导致的,比较简单的方法是:

yum install -y ntpdate
ntpdate ntp3.aliyun.com

之后,再次请求,问题解决,测试通过

  1. kubeadmin join加入节点报错:error execution phase preflight: unable to fetch the kubeadm-config ConfigMap: failed to get config map: Unauthorized

  2. k8s集群slave节点使用kubectl命令时The connection to the server localhost:8080 was refused - did you specify the right host or port?

3. kubeadm init 的工作流程

当你执行 kubeadm init 指令后,kubeadm 首先要做的,是一系列的检查工作,以确定这台机器可以用来部署 Kubernetes。这一步检查,我们称为“Preflight Checks”,它可以为你省掉很多后续的麻烦。

Preflight Checks 包括了很多方面,比如:

  • Linux 内核的版本必须是否是 3.10 以上?
  • Linux Cgroups 模块是否可用?
  • 机器的 hostname 是否标准?在 Kubernetes 项目里,机器的名字以及一切存储在 Etcd 中的 API 对象,都必须使用标准的 DNS 命名(RFC 1123)。
  • 用户安装的 kubeadm 和 kubelet 的版本是否匹配?
  • 机器上是不是已经安装了 Kubernetes 的二进制文件?
  • Kubernetes 的工作端口 10250/10251/10252 端口是不是已经被占用?
  • ip、mount 等 Linux 指令是否存在?
  • Docker 是否已经安装?
    ……

在通过了 Preflight Checks 之后,kubeadm 要为你做的,是生成 Kubernetes 对外提供服务所需的各种证书和对应的目录。

Kubernetes 对外提供服务时,除非专门开启“不安全模式”,否则都要通过 HTTPS 才能访问 kube-apiserver。这就需要为 Kubernetes 集群配置好证书文件。

kubeadm 为 Kubernetes 项目生成的证书文件都放在 Master 节点的 /etc/kubernetes/pki 目录下。在这个目录下,最主要的证书文件是 ca.crt 和对应的私钥 ca.key。

此外,用户使用 kubectl 获取容器日志等 streaming 操作时,需要通过 kube-apiserver 向 kubelet 发起请求,这个连接也必须是安全的。kubeadm 为这一步生成的是 apiserver-kubelet-client.crt 文件,对应的私钥是 apiserver-kubelet-client.key。

除此之外,Kubernetes 集群中还有 Aggregate APIServer 等特性,也需要用到专门的证书,这里我就不再一一列举了。需要指出的是,你可以选择不让 kubeadm 为你生成这些证书,而是拷贝现有的证书到如下证书的目录里:

/etc/kubernetes/pki/ca.{crt,key}

这时,kubeadm 就会跳过证书生成的步骤,把它完全交给用户处理。

**证书生成后,kubeadm 接下来会为其他组件生成访问 kube-apiserver 所需的配置文件。**这些文件的路径是:/etc/kubernetes/xxx.conf:

ls /etc/kubernetes/
admin.conf controller-manager.conf kubelet.conf scheduler.conf

这些文件里面记录的是,当前这个 Master 节点的服务器地址、监听端口、证书目录等信息。这样,对应的客户端(比如 scheduler,kubelet 等),可以直接加载相应的文件,使用里面的信息与 kube-apiserver 建立安全连接。

接下来,kubeadm 会为 Master 组件生成 Pod 配置文件。 Kubernetes 有三个 Master 组件 kube-apiserver、kube-controller-manager、kube-scheduler,而它们都会被使用 Pod 的方式部署起来。

你可能会有些疑问:这时,Kubernetes 集群尚不存在,难道 kubeadm 会直接执行 docker run 来启动这些容器吗?

当然不是。

在 Kubernetes 中,有一种特殊的容器启动方法叫做“Static Pod”。它允许你把要部署的 Pod 的 YAML 文件放在一个指定的目录里。这样,当这台机器上的 kubelet 启动时,它会自动检查这个目录,加载所有的 Pod YAML 文件,然后在这台机器上启动它们。

从这一点也可以看出,kubelet ( 每个节点上都运行一个 kubelet 服务进程,默认监听 10250 端口,接收并执行 master 发来的指令,管理 Pod 及 Pod 中的容器。)在 Kubernetes 项目中的地位非常高,在设计上它就是一个完全独立的组件,而其他 Master 组件,则更像是辅助性的系统容器。

从这一点也可以看出,kubelet 在 Kubernetes 项目中的地位非常高,在设计上它就是一个完全独立的组件,而其他 Master 组件,则更像是辅助性的系统容器。

在 kubeadm 中,Master 组件的 YAML 文件会被生成在 /etc/kubernetes/manifests 路径下。比如,kube-apiserver.yaml:

apiVersion: v1
kind: Pod
metadata:
 annotations:
 scheduler.alpha.kubernetes.io/critical-pod: ""
 creationTimestamp: null
 labels:
 component: kube-apiserver
 tier: control-plane
 name: kube-apiserver
 namespace: kube-system
spec:
 containers:
 - command:
 - kube-apiserver
 - --authorization-mode=Node,RBAC
 - --runtime-config=api/all=true
 - --advertise-address=10.168.0.2
 ...
 - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
 - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
 image: k8s.gcr.io/kube-apiserver-amd64:v1.11.1
 imagePullPolicy: IfNotPresent
 livenessProbe:
 ...
 name: kube-apiserver
 resources:
 requests:
 cpu: 250m
 volumeMounts:
 - mountPath: /usr/share/ca-certificates
 name: usr-share-ca-certificates
 readOnly: true
 ...
 hostNetwork: true
 priorityClassName: system-cluster-critical
 volumes:
 - hostPath:
 path: /etc/ca-certificates
 type: DirectoryOrCreate
 name: etc-ca-certificates
 ...

在这里,你需要关注这样几个信息:

  1. 这个 Pod 里只定义了一个容器,它使用的镜像是:k8s.gcr.io/kube-apiserver-amd64:v1.11.1 。这个镜像是 Kubernetes 官方维护的一个组件镜像。
  2. 这个容器的启动命令(commands)是 kube-apiserver --authorization-mode=Node,RBAC …,这样一句非常长的命令。其实,它就是容器里 kube-apiserver 这个二进制文件再加上指定的配置参数而已。
  3. 如果你要修改一个已有集群的 kube-apiserver 的配置,需要修改这个 YAML 文件。
  4. 这些组件的参数也可以在部署时指定,我很快就会讲解到。

在这一步完成后,kubeadm 还会再生成一个 Etcd 的 Pod YAML 文件,用来通过同样的 Static Pod 的方式启动 Etcd。所以,最后 Master 组件的 Pod YAML 文件如下所示:

$ ls /etc/kubernetes/manifests/
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml

而一旦这些 YAML 文件出现在被 kubelet 监视的 /etc/kubernetes/manifests 目录下,kubelet 就会自动创建这些 YAML 文件中定义的 Pod,即 Master 组件的容器。

Master 容器启动后,kubeadm 会通过检查 localhost:6443/healthz 这个 Master 组件的健康检查 URL,等待 Master 组件完全运行起来。

然后,kubeadm 就会为集群生成一个 bootstrap token。 在后面,只要持有这个 token,任何一个安装了 kubelet 和 kubadm 的节点,都可以通过 kubeadm join 加入到这个集群当中。

这个 token 的值和使用方法会,会在 kubeadm init 结束后被打印出来。

在 token 生成之后,kubeadm 会将 ca.crt 等 Master 节点的重要信息,通过 ConfigMap 的方式保存在 Etcd 当中,供后续部署 Node 节点使用。这个 ConfigMap 的名字是 cluster-info。

kubeadm init 的最后一步,就是安装默认插件。Kubernetes 默认 kube-proxy 和 DNS 这两个插件是必须安装的。它们分别用来提供整个集群的服务发现和 DNS 功能。 其实,这两个插件也只是两个容器镜像而已,所以 kubeadm 只要用 Kubernetes 客户端创建两个 Pod 就可以了。

4. kubeadm join 的工作流程

这个流程其实非常简单,kubeadm init 生成 bootstrap token 之后,你就可以在任意一台安装了 kubelet 和 kubeadm 的机器上执行 kubeadm join 了。

可是,为什么执行 kubeadm join 需要这样一个 token 呢?

因为,任何一台机器想要成为 Kubernetes 集群中的一个节点,就必须在集群的 kube-apiserver 上注册。可是,要想跟 apiserver 打交道,这台机器就必须要获取到相应的证书文件(CA 文件)。可是,为了能够一键安装,我们就不能让用户去 Master 节点上手动拷贝这些文件。

所以,kubeadm 至少需要发起一次“不安全模式”的访问到 kube-apiserver,从而拿到保存在 ConfigMap 中的 cluster-info(它保存了 APIServer 的授权信息)。而 bootstrap token,扮演的就是这个过程中的安全验证的角色。

只要有了 cluster-info 里的 kube-apiserver 的地址、端口、证书,kubelet 就可以以“安全模式”连接到 apiserver 上,这样一个新的节点就部署完成了。

接下来,你只要在其他节点上重复这个指令就可以了。

五、kubernetes安装dashboard web管理界面

【推荐直接参考git官网,有方法】官网:https://github.com/kubernetes/dashboard/releases
[k8s]kubernetes安装dashboard步骤
参考URL: https://www.jianshu.com/p/073577bdec98

k8s 默认没有 web 管理页面,可以通过安装呢 Dashboard 来增加一个管理界面

Kubernetes Dashboard 是一个管理Kubernetes集群的全功能Web界面,旨在以UI的方式完全替代命令行工具(kubectl 等)。

1. 下载dashboard的 yaml文件

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc1/aio/deploy/recommended.yaml

打开下载的文件添加一项:type: NodePort,暴露出去 Dashboard 端口,方便外部访问。

在这里插入图片描述官方的kubernetes-dashboard.yaml,我们首先将其下载下来:
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc1/aio/deploy/recommended.yaml

2. 下载kubernetes-dashboard docker镜像

在 yaml 文件 kubernetes-dashboard.yaml 中拉取了一个镜像 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1,没有配置 docker 代理网络的可能拉取不下来。
还是老思路,先从其他地方下载,然后再打tag

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1  k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1

vi kubernetes-dashboard.yaml
在如下位置,增加语句: (IfNotPresent→本地有则使用本地镜像,否则去镜像仓库拉取)
imagePullPolicy: IfNotPresent
在这里插入图片描述

3. 部署kubernetes-dashboard Pod

生成pod
kubectl apply -f recommended.yaml
# 查看是否
kubectl get pods --all-namespaces -o wide | grep dashboard

这里部署可能存在一个问题,在 yaml 文件 kubernetes-dashboard.yaml 中拉取了一个镜像 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1,没有配置 docker 代理网络的可能拉取不下来。
还是老思路,先从其他地方下载,然后再打tag

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1  k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1

修改获取镜像策略,使得在本地拉取镜像
重新安装dashboard

kubectl delete -f kubernetes-dashboard.yaml
kubectl create -f kubernetes-dashboard.yaml

发现当前最新版本的dashboard v2.0.0-rc1,定义了独立的命名空间,删除dashboard直接删除该命名空间即可:

kubectl delete ns kubernetes-dashboard

使用命令查看错误原因
kubectl --namespace=kube-system describe pod <pod_name>

4. 配置token认证

配置token认证也就是为dashboard创建相应的ServiceAccount并完成授权,并获取该ServiceAccount的token信息完成认证。

# 创建用于登陆dashboard的ServiceAccount
# 首先创建一个叫admin-user的服务账号,并放在kubernetes-dashboard名称空间
[root@master ~]# kubectl create serviceaccount admin-user -n kubernetes-dashboard
# 通过绑定clusterrole授权  
[root@master ~]# kubectl create clusterrolebinding admin-user --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user
# 查看 admin-user的token
[root@master ~]# kubectl -n kubernetes-dashboard get secret|awk '/^admin-user/{print $1}'
admin-user-token-w4psn
# 查看admin-user的token
kubectl describe secrets admin-user-token-w4psn -n kubernetes-dashboard

删除服务账号,相关命令

kubectl get sa --all-namespaces
#删除时必须指定命名空间
kubectl delete serviceaccount -n  kubernetes-dashboard admin-user

要让dashboard可以访问集群的各种资源,需要给dashboard账户赋予权限,这一步很关键,如果你缺少这一步的话,你打开dashboard后会报很多forbidden,如下:

configmaps is forbidden: User “system:serviceaccount:kube-system:service-controller” cannot list resource “configmaps” in API group “” in the namespace “default”
close
warning
persistentvolumeclaims is forbidden: User “system:serviceaccount:kube-system:service-controller” cannot list resource “persistentvolumeclaims” in API group “” in the namespace “default”
close
warning

5. 查看 Dashboard 端口号

新版本的bashboard使用新命名空间kubernetes-dashboard

[root@master ~]# kubectl get svc -n kubernetes-dashboard
NAME                        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.96.36.70   <none>        8000/TCP        5m6s
kubernetes-dashboard        NodePort    10.96.86.77   <none>        443:30816/TCP   5m6s
[root@master ~]# 

如上所示,Dashboard已经在30816端口上公开,现在可以在外部使用https://:31795进行访问。需要注意的是,在多节点的集群中,必须找到运行Dashboard节点的IP来访问,而不是Master节点的IP

Dashboard 会在 kube-system namespace 中创建自己的 Deployment 和 Service:

kubectl get service kubernetes-dashboard --namespace=kubernetes-dashboard
kubectl describe service kubernetes-dashboard --namespace=kubernetes-dashboard

6. 通过浏览器访问

Dashboard 支持 Kubeconfig 和 Token 两种认证方式,
认证有两种方式:

  • 通过我们刚刚获取的token直接认证
  • 通过Kubeconfig文件认证
    只需要在kubeadm生成的admin.conf文件末尾加上刚刚获取的token就好了。
  name: kubernetes-admin
  user:
    client-certificate-data: xxxxxxxx
    client-key-data: xxxxxx
    token: "在这里加上token"

7. 安装过程遇见问题整理

1)token登录web界面报错 the server could not find the requested resource
在这里插入图片描述问题分析,查看dashboard日志

[root@master log]# kubectl -n kube-system get pods -l k8s-app=kubernetes-dashboard
NAME                                    READY   STATUS    RESTARTS   AGE
kubernetes-dashboard-7c54d59f66-hv8d9   1/1     Running   0          15h
[root@master log]# kubectl -n kube-system logs kubernetes-dashboard-7c54d59f66-hv8d9

日志报错信息如下:

2020/01/14 01:38:44 Metric client health check failed: the server could not find the requested resource (get services heapster). Retrying in 30 seconds.
2020/01/14 01:39:14 Metric client health check failed: the server could not find the requested resource (get services heapster). Retrying in 30 seconds.

原因分析,dashboard版本比较老,新版本的dashboard有两个pod
在这里插入图片描述
网上解决方法:安装metric 或者用dashboard 新版本,查看bashboard发布官网
https://github.com/kubernetes/dashboard/releases,可以看到bashboard支持的k8s版本对应关系。

2) kubectl create clusterrolebinding报错Error from server (AlreadyExists): clusterrolebindings.rbac.authorization.k8s.io

[root@master ~]# kubectl create clusterrolebinding admin-user --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user
Error from server (AlreadyExists): clusterrolebindings.rbac.authorization.k8s.io "admin-user" already exists
[root@master ~]# kubectl describe clusterrolebinding admin-user
Name:         admin-user
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind            Name        Namespace
  ----            ----        ---------
  ServiceAccount  admin-user  kube-system

原因分析:之前执行过,把kube-system命名空间下的admin-user加到了
解决办法,如下命令kubectl delete clusterrolebinding 服务账号名

[root@master ~]# kubectl describe clusterrolebinding admin-user
Name:         admin-user
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind            Name        Namespace
  ----            ----        ---------
  ServiceAccount  admin-user  kube-system
[root@master ~]# kubectl delete clusterrolebinding admin-user
clusterrolebinding.rbac.authorization.k8s.io "admin-user" deleted

六、常见问题

master节点 报错 0/2 nodes are available: 2 node(s) had taints that the pod didn’t tolerate.

原因分析:
使用kubeadm部署的kubernetes集群,其master节点默认拒绝将pod调度运行于其上的,加点官方的术语就是:master默认被赋予了一个或者多个“污点(taints)”,“污点”的作用是让该节点拒绝将pod调度运行于其上。那么存在某些情况,比如想让master也成为工作节点可以调度pod运行怎么办呢?

两种方式:①去掉“污点”(taints)【生产环境不推荐】;②让pod能够容忍(tolerations)该节点上的“污点”。

查询所有节点信息,如下先查到你的节点名字(主机名)

[root@master ~]# kubectl get nodes
NAME                 STATUS     ROLES    AGE     VERSION
master.localdomain   NotReady   master   24h     v1.17.0
node1.localdomain    NotReady   <none>   6h16m   v1.17.0

master运行pod
kubectl taint nodes <节点名字> node-role.kubernetes.io/master-

kubectl taint nodes master.localdomain node-role.kubernetes.io/master-

master不运行pod
kubectl taint nodes <节点名字> node-role.kubernetes.io/master=:NoSchedule

查看 node1 上的 taint:
kubectl describe nodes node1

kubeadm init 后master一直处于notready状态

kubeadm init 后master一直处于notready状态
参考URL: https://blog.csdn.net/wangmiaoyan/article/details/101216496

kubeadm安装Kubernetes,集群状态检测时,master一直处于notready状态

kubectl get nodes

找问题,先查看pods状态

[root@master ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE
kube-system   coredns-58cc8c89f4-pkx82         0/1     Pending   0          34m
kube-system   coredns-58cc8c89f4-sddpq         0/1     Pending   0          34m
kube-system   etcd-master                      1/1     Running   0          34m
kube-system   kube-apiserver-master            1/1     Running   0          34m
kube-system   kube-controller-manager-master   1/1     Running   0          33m
kube-system   kube-proxy-4fj8z                 1/1     Running   0          10m
kube-system   kube-proxy-v54nh                 1/1     Running   0          34m
kube-system   kube-scheduler-master            1/1     Running   0          34m

发现coredns一直处于pending状态,再进一步看kuberctl.services日志

[root@master ~]# journalctl -f -u kubelet.service
-- Logs begin at Sat 2020-01-11 01:24:39 CST. --
Jan 11 08:14:24 master.localdomain kubelet[17032]: E0111 08:14:24.074459   17032 kubelet.go:2183] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
Jan 11 08:14:26 master.localdomain kubelet[17032]: W0111 08:14:26.542829   17032 cni.go:237] Unable to update cni config: no networks found in /etc/cni/net.d
Jan 11 08:14:29 master.localdomain kubelet[17032]: E0111 08:14:29.075465   17032 kubelet.go:2183] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

可以看到,显示NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
安装flannel

[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
[root@master ~]# 

如上,官方链接flannel不行,换个链接
master节点使用 kubectl apply -f 配置网络插件

[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

再查看集群状态,发现master正常了,处于ready状态;
但是node1节点还是处于notready状态,在master查看node节点的pod状态,显示ImagePullBackOff

[root@master pki]# kubectl get pods -n kube-system -o wide 
NAME                                         READY   STATUS                  RESTARTS   AGE    IP               NODE                 NOMINATED NODE   READINESS GATES
...
kube-flannel-ds-amd64-lz4qm                  0/1     Init:ImagePullBackOff   0          48m    192.168.88.129   node1.localdomain    <none>           <none>
...

因此查看,master下载的flannel镜像,

[root@master pki]# docker images|grep fla
quay.io/coreos/flannel                                                           v0.11.0-amd64       ff281650a721        11 months ago       52.6MB
[root@master pki]# 

在node节点上,下载flannel镜像

docker pull registry.cn-hangzhou.aliyuncs.com/huya_k8s_gcr_io/coreos_flannel:v0.11.0-amd64
docker tag registry.cn-hangzhou.aliyuncs.com/huya_k8s_gcr_io/coreos_flannel:v0.11.0-amd64 quay.io/coreos/flannel:v0.11.0-amd64

再次查看节点状态,node也变成了ready,测试通过

[root@master ~]# kubectl get nodes
NAME                 STATUS   ROLES    AGE    VERSION
master.localdomain   Ready    master   2d8h   v1.17.0
node1.localdomain    Ready    <none>   104m   v1.17.0
[root@master ~]# 

K8S-Master修改IP地址之后,重新初始化的方法。

使用kubeadm命令,执行:kubeadm reset

七、参考

附003.Kubeadm部署Kubernetes
参考URL: https://www.cnblogs.com/itzgr/p/11050543.html
利用 kubeadm 创建高可用集群
官网文档:https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/high-availability/

已标记关键词 清除标记
相关推荐
<p> <span style="color:#333333;">Kubernetes</span><span style="color:#333333;">是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。</span> </p> <p> <span style="color:#333333;"><br /></span> </p> <p> <span style="color:#333333;">在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。</span> </p> <p> <span style="color:#333333;"> </span> </p> <p> <span style="color:#333333;">K8s</span><span style="color:#333333;">网络在kubernetes的管理中是不可或缺的部分,本套课程主要围绕目前主流的flannel和calico两个网络组件进行讲解。还深入的剖析了calico和k8s网络策略等。</span> </p> <p> <br /></p> <p> <span style="color:#333333;">主要讲解K8S网络的以下几个方面:</span> </p> <p> <span style="color:#333333;">  1. Flannel</span><span style="color:#333333;">网络在k8s中的应用,及三种后端模式的演示。</span> </p> <p> <span style="color:#333333;">  2. Calico</span><span style="color:#333333;">网络在k8s中的架构及部署。</span> </p> <p> <span style="color:#333333;">  3. Calico</span><span style="color:#333333;">各选项的调整及对网络性能的优化。</span> </p> <p> <span style="color:#333333;">  4. Calico</span><span style="color:#333333;">网络策略和K8s网络策略的常见用法及案例。</span> </p> <p> <span style="color:#333333;">  5. Calico</span><span style="color:#333333;">网络策略的高级使用场景,比如限制到k8s节点的流量及高并发流量的旁路等。</span> </p> <p> <span style="color:#333333;">  6. Flannel</span><span style="color:#333333;">网络的迁移及和calico策略的集成。</span> </p> <p> <span style="color:#333333;"><br /></span> </p> <p> <span style="color:#FF0000;">注意: 本课程学习需要具有一定的Linux基础,网络基础,至少需要您了解网络七层协议,路由等基础知识,并掌握Docker和k8s相关知识点。</span> </p> <p> <span style="color:#FF0000;"><br /></span> </p> <p> <span style="color:#FF0000;"><img src="https://img-bss.csdn.net/202003160241495369.png" alt="" /><br /></span> </p> <p> <span style="color:#FF0000;"><br /></span> </p> <p> <span style="color:#FF0000;"><img src="https://img-bss.csdn.net/202003160242041406.png" alt="" /><br /></span> </p> <p> <span style="color:#FF0000;"><img src="https://img-bss.csdn.net/202003160242183493.png" alt="" /><br /></span> </p>
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值