文章目录
一、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) 环境介绍
系统类型 | IP | role | cpu | memory | hostname |
---|---|---|---|---|---|
CentOS 7.4.1708 | 192.168.13.100 | master | 2 | 2G | master.localdomain |
CentOS 7.4.1708 | 192.168.13.101 | master | 1 | 1G | node1.localdomain |
CentOS 7.4.1708 | 192.168.13.102 | master | 1 | 1G | node2.localdomain |
- 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
- 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
- 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
- 禁用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
需要注意几点:
-
网卡设置
kubeadm init操作会自动发现master节点的网卡设备,并且将其设置成默认网关。如果我们想使用不同的网络接口,可以使用 --apiserver-advertise-address= 参数来设置–apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。
-
注意一点是创建集群(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. 安装遇到问题整理
- [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
- 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服务的初始化。
- [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
- [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
-
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 -
kubeadmin join加入节点报错: x509: certificate has expired or is not yet valid的解决
计入
可能是由于时间不同步导致的,比较简单的方法是:
yum install -y ntpdate
ntpdate ntp3.aliyun.com
之后,再次请求,问题解决,测试通过
-
kubeadmin join加入节点报错:error execution phase preflight: unable to fetch the kubeadm-config ConfigMap: failed to get config map: Unauthorized
-
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
...
在这里,你需要关注这样几个信息:
- 这个 Pod 里只定义了一个容器,它使用的镜像是:k8s.gcr.io/kube-apiserver-amd64:v1.11.1 。这个镜像是 Kubernetes 官方维护的一个组件镜像。
- 这个容器的启动命令(commands)是 kube-apiserver --authorization-mode=Node,RBAC …,这样一句非常长的命令。其实,它就是容器里 kube-apiserver 这个二进制文件再加上指定的配置参数而已。
- 如果你要修改一个已有集群的 kube-apiserver 的配置,需要修改这个 YAML 文件。
- 这些组件的参数也可以在部署时指定,我很快就会讲解到。
在这一步完成后,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/