CentOS 7.3 Kubernetes 1.18.6 安装实战手册
CentOS 7.3 Kubernetes 1.17.3 部署过程_jaccheu的博客-CSDN博客
https://www.jianshu.com/p/32ccb9abdf88
- 环境装备:
三台 主机,OS:CentOS 7.3
如安装过需要按如下方法清空环境
kubeadm reset -f
modprobe -r ipip
lsmod
rm -rf ~/.kube/
rm -rf /etc/kubernetes/
rm -rf /etc/systemd/system/kubelet.service.d
rm -rf /etc/systemd/system/kubelet.service
rm -rf /usr/bin/kube*
rm -rf /etc/cni
rm -rf /opt/cni
rm -rf /var/lib/etcd
rm -rf /var/etcd
yum clean all
yum remove kube*
- 准备工作(master和node)
所有主机操作如下:
1,修改hosts文件
vi /etc/hosts
#加入下面3行
10.170.49.11 master
10.170.49.22 master
10.170.49.33 master
10.170.49.44 node
对应修改对应的主机名,然后重启
hostnamectl set-hostname master
reboot
2,禁用swap设备
#临时禁用
swapoff -a
#永久禁用
vim /etc/fstab
注释掉 /dev/mapper/VloGroup-lv_swap swap 所在的行
3,关闭系统默认防火墙(iptables和selinux)
sed -i -r "/^SELINUX=/c SELINUX=disabled" /etc/selinux/config
systemctl stop firewalld
systemctl disable firewalld
systemctl stop iptables
systemctl disable iptables
4、安装docker
下面的安装都是以root用户运行
## 安装所需的包
yum install -y yum-utils device-mapper-persistent-data lvm2
## 建议使用阿里云
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
## 安装最新版本docker
yum install docker-ce docker-ce-cli containerd.io
## 安装指定版本19.03(官方推荐版本)
yum install -y containerd.io-1.2.13 docker-ce-19.03.11 docker-ce-cli-19.03.11
## 配置远程
vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375 md
systemctl daemon-reload
systemctl restart docker
#启动Docker并设置开机运行
systemctl enable docker
systemctl start docker
systemctl status docker
## 查看docker信息
docker info
5、Docker服务配置公司代理
mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://username:passw0rd@proxy.neusoft.com:8080/"
Environment="NO_PROXY=localhost,127.0.0.1,192.168.131.211,192.168.131.217"
EOF
systemctl daemon-reload && systemctl restart docker
systemctl show --property=Environment docker
6、拉取K8S相关镜像脚本 :
Vi pull-k8s-1.18.6.sh
#!/bin/bash
images=(
kube-apiserver:v1.18.6
kube-controller-manager:v1.18.6
kube-scheduler:v1.18.6
kube-proxy:v1.18.6
pause:3.2
etcd:3.4.3-0
coredns:1.6.7
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
#保存退出
chmod +x pull-k8s.sh
./ pull-k8s-1.18.6.sh
7、kube-flannel镜像准备
Mkdir /etc/kubernate/yml/
Cd /etc/kubernate/yml/
下载镜像:
https://github.com/flannel-io/flannel/releases/download/v0.14.0/flanneld-v0.14.0-amd64.docker
上传到docker中
Docker load < flanneld-v0.14.0-amd64.docker
8,修改系统参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf
- 安装Master(mongo07)节点
1,启用ipvs
创建内核模块载入相关的脚本文件/etc/sysconfig/modules/ipvs.modules,设定自动载入的内核模块。文件内容如下:
Vi /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
ipvs_mods_dir="/usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs"
for i in $(ls $ipvs_mods_dir | grep -o "^[^.]*"); do
/sbin/modinfo -F filename $i &> /dev/null
if [ $? -eq 0 ]; then
/sbin/modprobe $i
fi
done
#运行并检查
chmod +x /etc/sysconfig/modules/ipvs.modules
/etc/sysconfig/modules/ipvs.modules
lsmod | grep ip_vs
2,修改系统参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf
3,增加kubernetes源
vi /etc/yum.repos.d/k8s.repo
[kubernetes]
name=Kubernetes Repository
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enble=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.pgp
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-key.gpg
如果在下一步安装时报如下错误
GPG key retrieval failed: [Errno 14] HTTPS Error 404 - Not Found
把上面的gpgcheck=1改为0
4,安装kubeadm、kubectl、kubelet
yum install -y kubelet-1.18.6 kubeadm-1.18.6 kubectl--1.18.6
yum -y upgrade systemd
systemctl enable kubelet.service
5, 安装systemd模块
vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375 --exec-opt native.cgroupdriver=systemd
systemctl daemon-reload
systemctl restart docker
6初始化集群Master节点
#查看所需的镜像列表,因为google镜像无法国内无法访问,拿到镜像列表后从阿里云镜像站点拉取
kubeadm config images list
kubeadm init --kubernetes-version=v1.18.6 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.1.0.0/16 --upload-certs | tee kubeadm-init.log
7、kubeadm-init.log中记录node加入指令:
kubeadm join 10.170.49.11:6443 --token p30zpo.gxeejju7mz3zjshg \
--discovery-token-ca-cert-hash sha256:831837f6c77a83c07667df3169a4cb6d0a8736f2c19a45bb174a2ed88f1f599b
8普通用户执行权限
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
## 或者root执行
export KUBECONFIG=/etc/kubernetes/admin.conf
错误问题1:
journalctl -xefu kubelet
Failed to start ContainerManager failed to initialize top level QOS containers: failed to update top level Burstable QOS cgroup : failed to set supported cgroup subsystems for cgroup [kubepods burstable]: failed to find subsystem mount for required subsystem: pids
解决方法:
在kubelet服务文件启动项加上
–feature-gates SupportPodPidsLimit=false --feature-gates SupportNodePidsLimit=false
操作:
vi /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
#发现ExecStart=后面添加参数
ExecStart="--feature-gates SupportPodPidsLimit=false --feature-gates SupportNodePidsLimit=false"
#或者更改引用变量$KUBELET_EXTRA_ARGS
下面好用:
vi /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--feature-gates SupportPodPidsLimit=false --feature-gates SupportNodePidsLimit=false
9安装Pod网络插件
Cd /etc/kubernate/yml/
下载kube-flannel.yml
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
10查看 :
kubectl get nodes
kubectl get pods -A
kubectl describe pods kube-flannel-ds-kg8jb -n kube-system
kubectl get pod -n kube-system -o wide
重新初始化:
Kuubeadm reset 输入y
11设置集群角色
因为master节点同时当node节点用,需要把master标签和污点去掉,默认master无法调度
# 去除master标签
kubectl label node mongo07 node-role.kubernetes.io/master-
# 去除污点
kubectl taint node k8s-m1 node-role.kubernetes.io/master:NoSchedule-
设置master 为 master 角色
[root@master ~]# kubectl label node master node-role.kubernetes.io/master=
kubectl taint nodes master node-role.kubernetes.io/master=true:NoSchedule
12、基本操作指令
kubectl get nodes
kubectl get pods -A
kubectl delete pod --grace-period=0 --force --namespace [NAMESPACE] [POD_NAME]
kubectl get namespace
kubectl get deployment --all-namespaces
kubectl get svc --all-namespaces
kubectl get pods --all-namespaces
kubectl get pod -o wide --all-namespaces
kubectl describe service/kubernetes-dashboard --namespace="kube-system"
kubectl describe pod/kubernetes-dashboard-468712587-754dc --namespace="kube-system"
kubectl delete pod/kubernetes-dashboard-468712587-754dc --namespace="kube-system"--grace-period=0 --force
13、实现多k8s集群切换
https://blog.csdn.net/weixin_34883093/article/details/113366912
首先将多k8s的/root/.kub/config文件合并到一个文档中,并上传到某一台k8s-master中的/root/.kub/config
[root@mongo07 .kube]#kubectl config view
[root@mongo07 .kube]#kubectl config get-contexts
[root@mongo07 .kube]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
internal internalCluster user
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
[root@mongo07 .kube]#kubectl config use-context { clusters Name}
Switched to context "fralychen1". # 表示切换成功
[root@mongo07 .kube]#kubectl get po -A -o wide
- 安装node节点
1指定版本
yum install -y kubelet-1.18.6 kubeadm-1.18.6
## kubelet自启动
systemctl enable kubelet
systemctl start kubelet
2将该节点加入的k8s集群,复制master成功后的命令:
执行master中kubeadm-init.log中记录node加入指令:
kubeadm join 10.170.49.11:6443 --token p30zpo.gxeejju7mz3zjshg \
--discovery-token-ca-cert-hash sha256:831837f6c77a83c07667df3169a4cb6d0a8736f2c19a45bb174a2ed88f1f599b
3如果想在一个普通的k8s节点使用kubectl命令:
复制master下的admin.conf到node节点相同的目录
/etc/kubernetes/admin.conf
### 然后重置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile
source /etc/profile
4.常用指令
kubectl get cs #查看master资源状态
kubectl get node #查看节点
kubectl cluster-info #查看集群状态
kubectl describe pods [pod名] #查看各类资源状态
kubectl get pods -o wide #查看更新信息
kubectl top node mongo05
这种方式直接进入nginx pod 里的容器里了
kubectl exec -it nginx sh
如果pod中有多个容器,可以选择进入某个容器
kubectl describe pods nginx
接下来我们可以通过-c 选项进入指定容器
kubectl exec -c 容器id
我们启动pod后,容器运行在pod中,外界无法访问,需要将pod的端口暴漏出去
kubectl port-forward nginx 8080:80
这样就将nginx容器内部的80端口映射为本机的8080端口,可以通过127.0.0.1:8080访问nginx服务了。
查看运行pod
kubectl get pods
当我们删除其中一个pod时,controller会重新启动一个pod,保证副本数为三个
kubectl delete pods nginx-6r92b
扩充副本数量
kubectl scale rc nginx --replicas=2
- 在k8s中使用harbor仓库中的docker镜像
参考:从harbor部署到在k8s中使用 - W-D - 博客园
- 修改每个node上的docker认证仓库
将每个node节点上的docker同样需要配置可信任仓库
vi /etc/docker/daemon.json
{
"insecure-registries":["192.168.131.217"]
}
- 创建认证secret
由于harbor采用了用户名密码认证,所以在镜像下载时需要配置sercet
#创建
kubectl create secret docker-registry registry-secret --namespace=default \
--docker-server=192.168.131.217 \
--docker-email wangj.neu@neusoft.com \
--docker-username=wangj.neu\
--docker-password=’*****’
kubectl create secret docker-registry registry-secret --namespace=default --docker-server=192.168.131.217 --docker-email wangj.neu@neusoft.com --docker-username=wangj.neu --docker-password=’*****’
#查看secret
[root@master demo]# kubectl get secret
NAME TYPE DATA AGE
default-token-gdwgn kubernetes.io/service-account-token 3 2d18h
registry-secret kubernetes.io/dockerconfigjson 1 116s
#删除
kubectl delete secret registry-secret
- 部署示例
以一个部署一个springbootdemo为例子,其中需要把containers中的images镜像指定为harbor仓库镜像地址,并且使用创建的的secret。
# kubectl create –f springbootdemo.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: springbootdemo-deployment
labels:
appname: springbootdemo
spec:
replicas: 1 #复本数
selector:
matchLabels:
appname: springbootdemo
template:
metadata:
labels:
appname: springbootdemo
spec:
containers:
- name: springbootdemo
image: 192.168.131.217/idea/springbootdocker:latest #镜像地址
ports:
- name: web1
containerPort: 8082 #springboot工程jar端口8082
hostPort: 8082 #k8s调度pod容器对应node主机暴露端口
imagePullSecrets: #使用的secret
- name: registry-secret
- kubernetes 之Guestbook 留言板
https://blog.csdn.net/zuopiezia/article/details/79299062?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.base
- Kubernetes之Pod、 Replicaset、 Service、Deployment和Label
ReplicationController、Pod和Service连接逻辑
Kubernetes的基本构件是Pod,ReplicationController、Pod和Service连接逻辑是这样的:
--通过kubectl run命令创建ReplicationController
--由ReplicationController,创建并维护一个或者多个Pod实例
--为了使Pod能够从集群外部访问,kubernetes将该ReplicationController管理的所有Pod由一个Service统一进行暴露
Pod是一个逻辑概念,它是Kubernetes资源调度的单元,一般会把一组功能强相关的容器逻辑上称之为一个pod,Pod就是所说的实例。作为一个逻辑概念,pod本身没有资源,pod中的容器具有资源,创建pod,可以通过定义pod模块。
Pod是一组紧密关联的容器集合,它们共享PID、IPC、Network和UTS namespace,是Kubernetes调度的基本单位。Pod的设计理念是支持多个容器在一个Pod中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务.
缺点: 不支持高并发, 高可用, 当Pod当机后无法自动恢复。
Pod:
- Pod
{
"kind": "Pod",(资源类型)
"apiVersion": "v1", (资源版本)
"metadata": {
"name": "app-tomcat", (名字,唯一)
"namespace": "default", (命名空间默认default)
"labels": {
"name": "app-tomcat" (label做为标识,可以跟RC,Service关联对应)
}
},
"spec": {
"containers": [
{
"name": "app-tomcat", (自定义镜像名称)
"image": "tomcat", (要拉取的镜像)
"command": [ (运行容器时,要运行的命令)
"/bin/bash",
"/opt/apache-tomcat-7.0.57/bin/catalina.sh",
"run"
],
"env": [ (环境变量K,V)
{
"name": "url_addr",
"value": "http://192.168.54.66:8080/paas/jsp/index.jsp"
}
],
"resources": { (对容器资源限制)
"limits": {
"cpu": "1",
"memory": "1073741824"
},
"requests": {
"cpu": "100m",
"memory": "104857600"
}
},
"imagePullPolicy": "Always" (获取镜像策略Always,Never,IfNotPresent)
}
],
"restartPolicy": "Always", (pod重启策略,Always,OnFailure,Never)
"dnsPolicy": "ClusterFirst",
"nodeSelector": { (选择将该pod调度到包含这些label的Node上)
"group": "node1"
}
}
}
Pod的状态
pods生命周期
状态 描述 Pending 容器尚未启动成功,它包括从pod被创建到调度、然后到拉镜像开始部署这个过程 Running 容器启动成功 Succeeded 容器退出,返回码是0,并且容器不会再被重新启动 Failed 容器异常退出 Unknown 状态未知,获取不到容器的状态,当出现异常时会有这种状态,例如pod所在的机器故障,或者pod所在的机器上Kubernetes的组件异常。
创建Pod
# vi pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- image: httpd
name: httpd
imagePullPolicy: Always
# kubectl create -f pod.yaml
查看Pod
# kubectl get pods
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 8d
# kubectl describe pods
删除Pod
# kubectl delete pod demo
- ReplicationController
ReplicationController(简称rc)是pod的复制抽象,用于解决pod的扩容缩容问题。通常,分布式应用为了性能或高可用性的考虑,需要复制多份资源,并且根据负载情况动态伸缩。通过replicationController,我们可以指定一个应用需要几份复制,Kubernetes将为每份复制创建一个pod,并且保证实际运行pod数量总是与该复制数量相等(例如,当前某个pod宕机时,自动创建新的pod来替换)。
RC中selector设置一个label,去关联pod的label,selector的label与pod的label相同,那么该pod就是该rc的一个实例;RC中Replicas设置副本数大小,系统根据该值维护pod的副本数。
Replicaset在继承Pod的所有特性的同时, 它可以利用预先创建好的模板定义副本数量并自动控制, 通过改变Pod副本数量实现Pod的扩容和缩容
缺点: 无法修改template模板, 也就无法发布新的镜像版本
RC模块(内置pod模块):
{
"kind": "ReplicationController",
"apiVersion": "v1",
"metadata": {
"name": "app-tomcat",
"namespace": "default",
"labels": {
"name": "app-tomcat"
}
},
"spec": {
"replicas": 2(副本数),
"selector": {
"name": "app-tomcat(选择的pod的label)"
},
"template": {
"metadata": {
"labels": {
"name": "app-tomcat(pod的label)"
}
},
"spec": {
"containers": [
{
"name": "kaifa2-group-tomcat",
"image": "192.168.54.64:5000/tomcat-248:V1.0",
"command": [
"/bin/bash",
"/opt/apache-tomcat-7.0.57/bin/catalina.sh",
"run"
],
"env": [
{
"name": "url_addr",
"value": "http://192.168.54.64:8080/paas/jsp/index.jsp"
}
],
"resources": {
"limits": {
"cpu": "1",
"memory": "1073741824"
},
"requests": {
"cpu": "100m",
"memory": "104857600"
}
},
"imagePullPolicy": "Always"
}
],
"restartPolicy": "Always",
"nodeSelector": {
"group": "node1"
}
}
}
}
}
- 创建Replicaset
# vi replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: demo-rc
labels:
app: demo-rc
spec:
replicas: 2
selector:
matchLabels:
app: demo-rc
template:
metadata:
labels:
app: demo-rc
spec:
containers:
- name: httpd
image: httpd
imagePullPolicy: Always
# kubectl create -f replicaset.yaml
查看replicaset
# kubectl get replicaset
NAME READY STATUS RESTARTS AGE
demo-rc 1/1 Running 0 8d
# kubectl describe replicaset
删除replicaset
# kubectl delete replicaset demo-rc
- Service
service是pod的路由代理抽象,用于解决pod之间的服务发现问题,即上下游pod之间使用的问题。传统部署方式中,实例所在的主机ip(或者dns名字)一般是不会改变的,但是pod的运行状态可动态变化(比如容器重启、切换机器了、缩容过程中被终止了等),所以访问端不能以写死IP的方式去访问该pod提供的服务。service的引入旨在保证pod的动态变化对访问端透明,访问端只需要知道service的地址,由service来提供代理。
Service的模板:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "tomcat-yefp",
"namespace": "default",
"labels": {
"name": "tomcat-yefp"
}
},
"spec": {
"ports": [
{
"protocol": "TCP",
"port": 8080(访问端口),
"targetPort": 8080
}
],
"selector": {
"name": "app-tomcat(选择的pod的label)"
},
"type": "ClusterIP",
"sessionAffinity": "None"
}
}
- EndPoint
Endpoint是可被访问的服务端点,即一个状态为running的pod,它是service访问的落点,只有service关联的pod才可能成为endpoint。
- Endpoint、service和pod的关系:
更改NodePort限制
Kubernetes默认对外的NodePort限制范围为30000-32767, 这里如果要使用一些常用的端口(80, 8080, 443)需将这个范围放大.
# vi /etc/kubernetes/manifests/kube-apiserver.yaml
在--service-cluster-ip-range与insecure-port间添加如下node port配置
- --service-cluster-ip-range=10.96.0.0/12
- --service-node-port-range=0-32767
- --insecure-port=0
重启服务
# systemctl restart kubelet
创建Service
# vi svc.yaml
apiVersion: v1
kind: Service
metadata:
name: demo
spec:
type: NodePort
ports:
- port: 80
nodePort: 80
selector:
app: httpd-demo
# kubectl create -f svc.yaml
Tip: 如果要对某一Pod或deployment添加对外访问端口, 这里service添加的selector的键值需与之相对应.
查看开放端口
# kubectl get svc demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo NodePort 10.100.96.157 <none> 80:80/TCP 1h
# kubectl describe service demo
Name: demo
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=httpd-demo
Type: NodePort
IP: 10.100.96.157
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 80/TCP
Endpoints: 10.244.0.36:80,10.244.0.37:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
- Deployment
Deployment在继承Pod和Replicaset的所有特性的同时, 它可以实现对template模板进行实时滚动更新并具备我们线上的Application life circle的特性.
创建Deployment
# vi deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
labels:
app: httpd-deployment
spec:
replicas: 2
selector:
matchLabels:
app: httpd-demo
template:
metadata:
labels:
app: httpd-demo
spec:
containers:
- name: httpd
image: httpd
imagePullPolicy: Always
ports:
- containerPort: 80
env:
- name: VERSION
value: "v1"
# kubectl create -f deployment.yaml
查看Deployment
# kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
httpd-deployment 2 2 2 2 8d
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
httpd-deployment-956697567-8mqch 1/1 Running 0 8d 10.244.0.36 kube-master
httpd-deployment-956697567-wcbs6 1/1 Running 0 8d 10.244.0.37 kube-master
# kubectl describe deployment
更新deployment
通过此命令可以呼出vi编辑器对模板进行编辑.
# kubectl edit -f deployment.yaml
通过此命令使当前编辑结果生效.
# kubectl apply -f deployment.yaml
再次查看可以看到老版本的deployment已经下架, 新版本的已经生效.
# kubectl get deployment
NAME DESIRED CURRENT READY AGE
httpd-deployment-6b98d94474 0 0 0 1m
httpd-deployment-956697567 2 2 2 7m
扩容与缩容
可以修改replicas的赋值对deployment进行扩容与缩容
# kubectl scale deployment/httpd-deployment --replicas=1
删除deployment
# kubectl delete deployment httpd-deployment
- Lable
Label是attach到Pod的一对键/值对,用来传递用户定义的属性。比如,你可能创建了一个"tier"和“app”标签,通过Label(tier=frontend, app=myapp)来标记前端Pod容器,使用Label(tier=backend, app=myapp)标记后台Pod。然后可以使用Selectors选择带有特定Label的Pod,让具体某一个Pod或者Deployment去使用某一个Service实现特定的网络配置.
原文链接:https://blog.csdn.net/bbwangj/article/details/81812675
Pod是一个或多个容器的组合,这些容器共享存储、网络和命名空间,以及如何运行的规范。Pod是Kubernetes的最小可部署单元。Pod的中文译词是豌豆荚,docker容器就像是豆子运行在豌豆荚内。
- Kubernetes资源对象Pod、ReplicaSet、Deployment、Service之间的关系
- ReplicaSet:
先说下Replication Controller。Replication Controller的作用是确保Pod以指定的副本个数运行。
ReplicaSet是Replication Controller升级版。ReplicaSet和Replication Controller之间的唯一区别是对选择器支持。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1.0,v2.0)或env notin (dev, qa))。
在yaml文件中通过spec.replicas声明pod的副本数。
- Deployment:
Deployment用于管理Pod、ReplicaSet,可实现滚动升级和回滚应用、扩容和缩容。
- Service:
试想一个问题,ReplicaSet定义了pod的数量是2,当一个pod由于某种原因停止了,ReplicaSet会新建一个pod,以确保运行中的pod数量始终是2。但每个pod都有自己的ip,前端请求不知道这个新pod的ip是什么,那前端的请求如何发送到新pod中呢?
答案是使用Service
k8s的Service定义了一个服务的访问入口地址,前端的应用通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,来自外部的访问请求被负载均衡到后端的各个容器应用上。Service与其后端Pod副本集群之间则是通过Label Selector实现关联。
请说人话:前端请求不是直接发送给Pod,而是发送到Service,Service再将请求转发给pod。
总结一下:Pod被ReplicaSet管理,ReplicaSet控制pod的数量;ReplicaSet被Deployment管理,Deployment控制pod应用的升级、回滚,当然也能控制pod的数量。Service提供一个统一固定入口,负责将前端请求转发给Pod。
- 实践环节
定义一个myapp.yaml文件
apiVersion: apps/v1
# 声明一个Deployment资源对象
kind: Deployment
metadata:
name: deployment-myapp
spec:
# 通过replicas声明pod个数是2
replicas: 2
# 通过标签选择被控制的pod
selector:
matchLabels:
app: myapp
# 在template中定义pod
template:
metadata:
# 给pod打上标签app=myapp
labels:
app: myapp
spec:
containers:
# 声明容器名称,注意不是pod名称,pod名称应该定义在metadata中
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
# 在一个yaml文件中通过---分割多个资源对象
---
apiVersion: v1
# 声明一个Service资源对象
kind: Service
metadata:
name: service-myapp
spec:
# service-myapp将选择标签包含app=myapp的pod
selector:
app: myapp
ports:
- name: http
# Service监听端口
port: 80
# 转发到后端Pod的端口号
targetPort: 80
部署这个资源清单
kubectl apply -f myapp.yaml
先看一个很有意思的图片
myapp.yaml文件声明了deployment的名称,没声明ReplicaSet、Pod的名称。但kubernetes会自动给ReplicaSet、Pod起名称。
Deployment名称是deployment-myapp
ReplicaSet名称是deployment-myapp-5fdb5f69f,实际上是Deployment名称加上pod-template的hash值
Pod名称是deployment-myapp-5fdb5f69f-njrb6、deployment-myapp-5fdb5f69f-whpwg,实际上是ReplicaSet的名称加上一个hash值。
使用 kubectl describe svc service-myapp 命令看下service-myapp的详细信息。
可以看到service-myapp的ip地址是10.97.41.88。发送到10.97.41.88:80的请求会被转发给10.244.1.5:80或10.244.2.2:80
看下图:
先直接请求pod,获取pod的hostname
curl 10.244.1.5:80/hostname.html
curl 10.244.2.2:80/hostname.html
然后请求service-myapp,service-myapp会把请求负载给后端的pod
curl 10.97.41.88:80/hostname.html
还有一个很有意思的事情。pod能ping通,但是servic却ping不通
这是为什么呢?
答案:因为Service其实是iptables或ipvs的转发规则,这规则不支持ICMP协议,所以就ping不通咯。
1.your configuration file uses an old API spec: "kubeadm.k8s.io/v1alpha2".
执行kubeadm init --config /etc/kubernetes/kubeadm-master.config --ignore-preflight-errors=all报错
apiVersion: kubeadm.k8s.io/v1alpha3
kind: MasterConfiguration
2.The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp [::1]:10248: connect: connection refused.
vi /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/ --cni-bin-dir=/opt/cni/bin"
[root@localhost kubernetes]# vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --fail-swap-on=false"
[root@localhost kubernetes]# systemctl daemon-reload
[root@localhost kubernetes]# systemctl restart kubelet
3、etc/kubernetes/manifests/kube-apiserver.yaml already exists
rm -rf /etc/kubernetes/manifests
4.kubectl get pod状态为ErrImagePull && ImagePullBackOff ErrImageNeverPull,请确保node上有相应的镜像,没有则在node机器上进行docker pull,且deployment中imagePullPolicy:IfNotPresent
image: tomcat:8 #确保node节点上有该镜像且可正常运行,注意是node节点机器上,不是master机器
imagePullPolicy: IfNotPresent ##Always,IfNotPresent,Never
4、kubeadm初始化警告”cgroupfs“解决
编辑/usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
systemctl daemon-reload
systemctl restart docker
设置完成后通过docker info命令可以看到Cgroup Driver为systemd
docker info | grep Cgroup
5、错误“[ERROR DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty”
rm -rf /var/lib/etcd
6、kubectl Unable to connect to the server: dial tcp 10.12.2.199:6443: i/o timeout
原因是 Master 节点初始化集群的时候,没有执行:
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
#192.168.0.49为master节点
7、token只有24小时有效,重新生成:
[root@mongo07 kubernetes]#kubeadm token create
#token和ca证书sha256编码hash值可通过以下命令获取:
kubeadm token list
a、获取:--token
[root@mongo07 kubernetes]# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
852nz6.eiyznm85rnacn775 23h 2021-08-17T16:36:21+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
b、获取 --discovery-token-ca-cert-hash sha256:
[root@mongo07 kubernetes]#openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
831837f6c77a83c07667df3169a4cb6d0a8736f2c19a45bb174a2ed88f1f599b
将node加入集群
kubeadm join 10.170.49.57:6443 --token 852nz6.eiyznm85rnacn775 --discovery-token-ca-cert-hash sha256:831837f6c77a83c07667df3169a4cb6d0a8736f2c19a45bb174a2ed88f1f599b
#查看日志
journalctl -f -u kubelet
8、kubeadm error execution phase preflight: couldn't validate the identity of the API Server: could not find a JWS signature in the cluster-info ConfigMap
原因:master节点的token过期了
解决:创建新的token
#得到token
>kubeadm token create
#得到discovery-token-ca-cert-hash
> openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
- 安装部署dashboard
https://www.cnblogs.com/sandshell/p/13637561.html
1.查看pod运行情况
[root@binghe101 ~]# kubectl get pods -A -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system calico-kube-controllers-5b8b769fcd-l2tmm 1/1 Running 2 15h 172.18.203.71 binghe101 <none> <none>
kube-system calico-node-7b7fx 1/1 Running 2 15h 192.168.175.102 binghe102 <none> <none>
kube-system calico-node-8krsl 1/1 Running 2 15h 192.168.175.101 binghe101 <none> <none>
kube-system coredns-546565776c-rd2zr 1/1 Running 2 15h 172.18.203.72 binghe101 <none> <none>
kube-system coredns-546565776c-x8r7l 1/1 Running 2 15h 172.18.203.73 binghe101 <none> <none>
kube-system etcd-binghe101 1/1 Running 2 15h 192.168.175.101 binghe101 <none> <none>
kube-system kube-apiserver-binghe101 1/1 Running 3 15h 192.168.175.101 binghe101 <none> <none>
kube-system kube-controller-manager-binghe101 1/1 Running 3 15h 192.168.175.101 binghe101 <none> <none>
kube-system kube-proxy-cgq5n 1/1 Running 2 15h 192.168.175.102 binghe102 <none> <none>
kube-system kube-proxy-qnffb 1/1 Running 2 15h 192.168.175.101 binghe101 <none> <none>
kube-system kube-scheduler-binghe101 1/1 Running 3 15h 192.168.175.101 binghe101 <none> <none>
kube-system metrics-server-57bc7f4584-cwsn8 1/1 Running 0 109m 172.18.229.68 binghe102 <none> <none>
2.下载recommended.yaml文件
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
3.修改recommended.yaml文件
vim recommended.yaml
需要修改的内容如下所示。
1 ---
2 kind: Service
3 apiVersion: v1
4 metadata:
5 labels:
6 k8s-app: kubernetes-dashboard
7 name: kubernetes-dashboard
8 namespace: kubernetes-dashboard
9 spec:
10 type: NodePort #增加
11 ports:
12 - port: 443
13 targetPort: 8443
14 nodePort: 30000 #增加
15 selector:
16 k8s-app: kubernetes-dashboard
17 ---
18 #因为自动生成的证书很多浏览器无法使用,所以我们自己创建,注释掉kubernetes-dashboard-certs对象声明
19 #apiVersion: v1
20 #kind: Secret
21 #metadata:
22 # labels:
23 # k8s-app: kubernetes-dashboard
24 # name: kubernetes-dashboard-certs
25 # namespace: kubernetes-dashboard
26 #type: Opaque
27 ---
- 创建证书
mkdir dashboard-certs
cd dashboard-certs/
#创建命名空间
kubectl create namespace kubernetes-dashboard
# 创建key文件
openssl genrsa -out dashboard.key 2048
#证书请求
openssl req -days 36000 -new -out dashboard.csr -key dashboard.key -subj '/CN=dashboard-cert'
#自签证书
openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt
#创建kubernetes-dashboard-certs对象
kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kubernetes-dashboard
5.安装dashboard
kubectl create -f ~/recommended.yaml
注意:这里可能会报如下所示。
Error from server (AlreadyExists): error when creating "./recommended.yaml": namespaces "kubernetes-dashboard" already exists
这是因为我们在创建证书时,已经创建了kubernetes-dashboard命名空间,所以,直接忽略此错误信息即可。
6.查看安装结果
1 [root@binghe101 ~]# kubectl get pods -A -o wide
2 NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3 kube-system calico-kube-controllers-5b8b769fcd-l2tmm 1/1 Running 2 15h 172.18.203.71 binghe101 <none> <none>
4 kube-system calico-node-7b7fx 1/1 Running 2 15h 192.168.175.102 binghe102 <none> <none>
5 kube-system calico-node-8krsl 1/1 Running 2 15h 192.168.175.101 binghe101 <none> <none>
6 kube-system coredns-546565776c-rd2zr 1/1 Running 2 15h 172.18.203.72 binghe101 <none> <none>
7 kube-system coredns-546565776c-x8r7l 1/1 Running 2 15h 172.18.203.73 binghe101 <none> <none>
8 kube-system etcd-binghe101 1/1 Running 2 15h 192.168.175.101 binghe101 <none> <none>
9 kube-system kube-apiserver-binghe101 1/1 Running 3 15h 192.168.175.101 binghe101 <none> <none>
10 kube-system kube-controller-manager-binghe101 1/1 Running 3 15h 192.168.175.101 binghe101 <none> <none>
11 kube-system kube-proxy-cgq5n 1/1 Running 2 15h 192.168.175.102 binghe102 <none> <none>
12 kube-system kube-proxy-qnffb 1/1 Running 2 15h 192.168.175.101 binghe101 <none> <none>
13 kube-system kube-scheduler-binghe101 1/1 Running 3 15h 192.168.175.101 binghe101 <none> <none>
14 kube-system metrics-server-57bc7f4584-cwsn8 1/1 Running 0 133m 172.18.229.68 binghe102 <none> <none>
15 kubernetes-dashboard dashboard-metrics-scraper-6b4884c9d5-qccwt 1/1 Running 0 102s 172.18.229.75 binghe102 <none> <none>
16 kubernetes-dashboard kubernetes-dashboard-7b544877d5-s8cgd 1/1 Running 0 102s 172.18.229.74 binghe102 <none> <none>
17 [root@binghe101 ~]# kubectl get service -n kubernetes-dashboard -o wide
18 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
19 dashboard-metrics-scraper ClusterIP 10.96.249.138 <none> 8000/TCP 2m21s k8s-app=dashboard-metrics-scraper
20 kubernetes-dashboard NodePort 10.96.219.128 <none> 443:30000/TCP 2m21s k8s-app=kubernetes-dashboard
7.创建dashboard管理员
创建dashboard-admin.yaml文件。
vim dashboard-admin.yaml
文件的内容如下所示。
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: dashboard-admin
namespace: kubernetes-dashboard
保存退出后执行如下命令创建管理员。
kubectl create -f ./dashboard-admin.yaml
8.为用户分配权限
创建dashboard-admin-bind-cluster-role.yaml文件。
vim dashboard-admin-bind-cluster-role.yaml
文件内容如下所示。
1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: ClusterRoleBinding
3 metadata:
4 name: dashboard-admin-bind-cluster-role
5 labels:
6 k8s-app: kubernetes-dashboard
7 roleRef:
8 apiGroup: rbac.authorization.k8s.io
9 kind: ClusterRole
10 name: cluster-admin
11 subjects:
12 - kind: ServiceAccount
13 name: dashboard-admin
14 namespace: kubernetes-dashboard
保存退出后执行如下命令为用户分配权限。
kubectl create -f ./dashboard-admin-bind-cluster-role.yaml
9.查看并复制用户Token
在命令行执行如下命令。
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep dashboard-admin | awk '{print $1}')
具体执行情况如下所示。
1 [root@binghe101 ~]# kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep dashboard-admin | awk '{print $1}')
2 Name: dashboard-admin-token-p8tng
3 Namespace: kubernetes-dashboard
4 Labels: <none>
5 Annotations: kubernetes.io/service-account.name: dashboard-admin
6 kubernetes.io/service-account.uid: c3640b5f-cd92-468c-ba01-c886290c41ca
7
8 Type: kubernetes.io/service-account-token
9
10 Data
11 ====
12 ca.crt: 1025 bytes
13 namespace: 20 bytes
14 token: eyJhbGciOiJSUzI1NiIsImtpZCI6IlVsRVBqTG5RNC1oTlpDS2xMRXF2cFIxWm44ZXhWeXlBRG5SdXpmQXpDdWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tcDh0bmciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYzM2NDBiNWYtY2Q5Mi00NjhjLWJhMDEtYzg4NjI5MGM0MWNhIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.XOrXofgbk5EDa8COxOkv31mYwciUGXcBD9TQrb6QTOfT2W4eEpAAZUzKYzSmxLeHMqvu_IUIUF2mU5Lt6wN3L93C2NLfV9jqaopfq0Q5GjgWNgGRZAgsuz5W3v_ntlKz0_VW3a7ix3QQSrEWLBF6YUPrzl8p3r8OVWpDUndjx-OXEw5pcYQLH1edy-tpQ6Bc8S1BnK-d4Zf-ZuBeH0X6orZKhdSWhj9WQDJUx6DBpjx9DUc9XecJY440HVti5hmaGyfd8v0ofgtdsSE7q1iizm-MffJpcp4PGnUU3hy1J-XIP0M-8SpAyg2Pu_-mQvFfoMxIPEEzpOrckfC1grlZ3g
可以看到,此时的Token值为:
1 eyJhbGciOiJSUzI1NiIsImtpZCI6IlVsRVBqTG5RNC1oTlpDS2xMRXF2cFIxWm44ZXhWeXlBRG5SdXpmQXpDdWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tcDh0bmciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYzM2NDBiNWYtY2Q5Mi00NjhjLWJhMDEtYzg4NjI5MGM0MWNhIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.XOrXofgbk5EDa8COxOkv31mYwciUGXcBD9TQrb6QTOfT2W4eEpAAZUzKYzSmxLeHMqvu_IUIUF2mU5Lt6wN3L93C2NLfV9jqaopfq0Q5GjgWNgGRZAgsuz5W3v_ntlKz0_VW3a7ix3QQSrEWLBF6YUPrzl8p3r8OVWpDUndjx-OXEw5pcYQLH1edy-tpQ6Bc8S1BnK-d4Zf-ZuBeH0X6orZKhdSWhj9WQDJUx6DBpjx9DUc9XecJY440HVti5hmaGyfd8v0ofgtdsSE7q1iizm-MffJpcp4PGnUU3hy1J-XIP0M-8SpAyg2Pu_-mQvFfoMxIPEEzpOrckfC1grlZ3g
10.查看dashboard界面
在浏览器中打开链接 https://192.168.175.101:30000 ,如下所示。

这里,我们选择Token方式登录,并输入在命令行获取到的Token,如下所示。

点击登录后进入dashboard,如下所示。

由于我们在《【K8S】K8s部署Metrics-Server服务》一文中安装了Metrics-Server服务,所以,我们可以查看节点服务器CPU和内存的使用情况,如下所示。

11.57登录Token
eyJhbGciOiJSUzI1NiIsImtpZCI6Im5iXy1jWjJRd1RJdFh0eEhkYndyYjVTd0dyMnkxWVhpbFBQbUlkNEZDYzAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tamtnbHYiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNTZhMmQzY2QtYzYxZS00MGY1LWI1ODQtYTFmN2YyZWUxOGI0Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.UxQ9Lu3Z8Fx-nt1Xa8ghr7blFZ3IhK4vWjOoeCzTvsyzBGHTSD1g3p8_jPR9uiLcm53OuC4eeE37SeMEOyXGjc6r8thtuUURy_7EfQKJJfVAjiIVr4sknYWvnuJd_HRvUDeEOTbeWW7VStO67y8nZDfCfu3CCEpIb6tr2YT6YCQjOUeqlZmIHKodfZHVKaxV6f6HPpie92IWESlO8L4Ofdl9ZIYfUsIyZTuvu0KN5e0rJSnrjAyWK3NdZqjmftGI7Mcl4VJ9-aZeFWBR5DM-XDo-H6nmvWPlWTIt4e7vLQLc-gVA5pOSy303QnQ_tQhjCTDJY-4H5TsFXbhOK_ps8g
12.用户登录方式
https://blog.csdn.net/ZouChengli/article/details/107284652
- 新增密码文件:
我们去master节点新增一个文件,如果是ha会有多个master,那么每个master同下操作。
里面内容结构是:用户名,密码(用户名和密码要保持一致),唯一ID。
echo "admin,admin,1" > /etc/kubernetes/pki/basic_auth_file
- 修改配置
# cat /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.168.100:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=192.168.168.100
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
- --insecure-port=0
- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --secure-port=6443
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-cluster-ip-range=10.1.0.0/16
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
- --basic-auth-file=/etc/kubernetes/pki/basic_auth_file # 就这一行是我新增的。大家不要搞错。
image: registry.cn-shanghai.aliyuncs.com/k8sgcrio_containers/kube-apiserver:v1.18.5
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 192.168.168.100
path: /healthz
port: 6443
scheme: HTTPS
initialDelaySeconds: 15
timeoutSeconds: 15
name: kube-apiserver
resources:
requests:
cpu: 250m
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/pki
name: etc-pki
readOnly: true
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- hostPath:
path: /etc/pki
type: DirectoryOrCreate
name: etc-pki
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
status: {}
- 改完会自动重启
手动更新
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
- 创建集群角色权限 绑定
kubectl create clusterrolebinding login-on-dashboard-with-cluster-admin --clusterrole=cluster-admin --user=admin
- 检查集群角色权限绑定
[root@mongo07 kubernetes]# kubectl get clusterrolebinding login-on-dashboard-with-cluster-admin
NAME ROLE AGE
login-on-dashboard-with-cluster-admin ClusterRole/cluster-admin 44s
- 最后修改recommended.yamlsglf yywr
recommended.yaml 是dashboard相关部署文件。我就截取了中间重要部分,以供大家参考。
# kubectl edit deploy kubernetes-dashboard -n kubernetes-dashboard
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
- --token-ttl=21600 #新增行 单位秒
- --authentication-mode=basic #新增行
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: registry.cn-shanghai.aliyuncs.com/dockerio_containers/kubernetesui-dashboard:v2.0.3
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
- --token-ttl=21600 #新增行 单位秒
- --authentication-mode=basic #新增行
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- 等待dashboard自动更新配置重启
手动更新
kubectl apply -f recommended.yaml
kubectl get pod -n kubernetes-dashboard
- 查看效果
13重新安装:
当pod已经被删除,并且卡在Terminated状态较长时间时
删除finalizers
删除pod的finalizers,运行命令:
kubectl patch pod[POD_NAME]-p'{"metadata":{"finalizers":null}}'
强制删除pod
请注意,这是解决方法不是解决方案,请谨慎行事确保问题不会进一步恶化。另外请参与Statefulset有关的详细信息。
强制删除运行命令:
kubectl delete pod --grace-period=0 --force --namespace [NAMESPACE] [POD_NAME]
即:
kubectldeletepod--grace-period=0--force--namespacekubernetes-dashboard kubernetes-dashboard-86488ff5dd-q7vlx
kubectldeletepod--grace-period=0--force--namespacekubernetes-dashboard dashboard-metrics-scraper-6b4884c9d5-qc6n6
1.批量删除pod
kubectl -n kube-system get po | awk ‘{print $1}‘ | xargs kubectl --kubeconfig=/etc/kubernetes/kubeconfig -n kube-system delete po
2.批量强制删除pod
kubectl get po -A -o wide | grep Terminating | awk ‘{print $2}’ | xargs kubectl --kubeconfig=/etc/kubernetes/kubeconfig -n kube-system delete po --grace-period=0 –force
删除 istio-system 中所有状态为:Terminating ContainerCreating
kubectl delete pod --grace-period=0 --force --namespace istio-system $(kubectl get po -A -o wide | grep Terminating | awk '{print $2}')
kubectl delete pod --grace-period=0 --force --namespace istio-system $(kubectl get po -A -o wide | grep ContainerCreating | awk '{print $2}')
删除exited 状态的容器
docker rm $(docker ps -q -f status=exited)
k8s批量删除Evicted Pods
kubectl -n kube-system get pods | grep Evicted
kubectl -n kube-system get pods | grep Evicted |awk '{print$1}'|xargs kubectl -n kube-system delete pods
kubectl -n istio-system get pods | grep Evicted |awk '{print$1}'|xargs kubectl -n istio-system delete pods
kubectl get pods | grep Evicted |awk '{print$1}'|xargs kubectl delete pods
kubectl -n kubernetes-dashboard get pods | grep Evicted |awk '{print$1}'|xargs kubectl -n kubernetes-dashboard delete pods
k8s中coredns启动失败
CoreDNS是k8s中,master节点和从节点及其pods之间通信的接口。
需要先进入 coredns的configmap然后删除他的loop然后保存退出
kubectl edit cm coredns -n kube-system
需要先进入 coredns的configmap然后删除他的loop然后保存退出
kubectl edit cm coredns -n kube-system
然后删除两个coredns pod
kubectl delete pod coredns-8686dcc4fd-859r5 coredns-8686dcc4fd-j9nfd -n kube-system
再次查看就行了
一直在termnating
https://blog.csdn.net/qq_40244755/article/details/112764837
背景:k8s集群重新安装kubernetes-dashboard出现了这个问题,使用了删除命名空间,但因为一直在termnating,所以导致无法有效删除.
k8s:unable to create new content in namespace kubernetes-dashboard because it is being terminated
解决办法:
1、查看命名空间:
kubectl get ns
2、查看kubernetes-dashboard的命名空间描述
kubectl get ns kubernetes-dashboard -o json > kubernetes-dashboard.json
3、编辑
sudo vim kubernetes-dashboard.json
删除spec
删除前
删除后
4、 打开一个新窗口运行kubectl proxy跑一个API代理在本地的8081端口
kubectl proxy --port=8081
5、curl删除
curl -k -H "Content-Type:application/json" -X PUT --data-binary @kubernetes-dashboard.json http://127.0.0.1:8081/api/v1/namespaces/kubernetes-dashboard/finalize
6、结果如下:
- 故障排除步骤
- Kubectl pod –A –o wide
查看状态,和对应的 node
- kubectl describe pod xxxx -n kkkk (查看问题)
一般是pod所在node的docker中没有pull下来相关images,可以手动pull,或者上传
- kubect delete pod xxxx
删除相关pod,等重拉镜像和重构容器
- Coredns状态,CoreDNS是k8s中,master节点和从节点及其pods之间通信的接口。参考Coredns启动失败
- 重启node中的docker。
- 重启node reboot
- 减少pod部署,达到内存释放
- 安装部署Metrics-Server
https://www.cnblogs.com/binghe001/p/12821804.html
- 简介
在新版的K8S中,系统资源的采集均使用Metrics-Server服务,可以通过Metrics-Server服务采集节点和Pod的内存、磁盘、CPU和网络的使用率等信息。说的具体点:新版K8S资源使用情况的度量(如容器的 CPU 和内存使用)可以通过 Metrics API 获取。
注意:
- Metrics API 只可以查询当前的度量数据,并不保存历史数据
- Metrics API URI 为
/apis/metrics.k8s.io/,在 k8s.io/metrics维护 - 必须部署 metrics-server 才能使用该 API,metrics-server 通过调用 Kubelet Summary API 获取数据
- metrics-server架构示意图:

- 下载并解压Metrics-Server
https://github.com/kubernetes-sigs/metrics-server/archive/v0.3.6.tar.gz
tar -zxvf v0.3.6.tar.gz
- 2.修改Metrics-Server配置文件
cd metrics-server-0.3.6/deploy/1.8+/
vim metrics-server-deployment.yaml
vim metrics-server-deployment.yaml文件原有的内容如下所示。
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
serviceAccountName: metrics-server
volumes:
# mount in tmp so we can safely use from-scratch images and/or read-only containers
- name: tmp-dir
emptyDir: {}
containers:
- name: metrics-server
image: k8s.gcr.io/metrics-server-amd64:v0.3.6
imagePullPolicy: Always
volumeMounts:
- name: tmp-dir
mountPath: /tmp
修改后的文件内容如下所示。
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
serviceAccountName: metrics-server
volumes:
# mount in tmp so we can safely use from-scratch images and/or read-only containers
- name: tmp-dir
emptyDir: {}
containers:
- name: metrics-server
# 修改image 和 imagePullPolicy
image: mirrorgooglecontainers/metrics-server-amd64:v0.3.6
imagePullPolicy: IfNotPresent
# 新增command配置
command:
- /metrics-server
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalDNS,InternalIP,ExternalDNS,ExternalIP,Hostname
volumeMounts:
- name: tmp-dir
mountPath: /tmp
# 新增resources配置
resources:
limits:
cpu: 300m
memory: 200Mi
requests:
cpu: 200m
memory: 100Mi
修改完metrics-server-deployment.yaml文件后保存退出。
- 3.安装Metrics-Server
执行如下命令安装Metrics-Server。
kubectl apply -f metrics-server-0.3.6/deploy/1.8+/
- 4.查看node信息
安装完Metrics-Server之后,查看node信息,如下所示。
kubectl get pod -n kube-system
metrics-server-57bc7f4584-ttgvk 1/1 Running 0 6m34s
[root@binghe101 ~]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
binghe101 141m 7% 1113Mi 65%
binghe102 62m 3% 549Mi 32%
binghe103 100m 5% 832Mi 48%
可以看到,使用Metrics-Server收集到节点信息,说明Metrics-Server安装成功。
- 注意事项
下载Metrics-Server安装文件之后,一定要修改metrics-server-deployment.yaml文件,在使用kubectl top node命令查看node信息时,会报如下错误。
error: metrics not available yet
- 问题排查
[root@k8s-master1 ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
如果kubectl get cs查询失败,可能是apiserver出现了问题。
#apiserver 正常可以通过该命令查看状态
[root@k8s-master1 ~]# kubectl cluster-info
Kubernetes master is running at https://10.0.0.63:6443
KubeDNS is running at https://10.0.0.63:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
# 通过dump.log查看集群问题
[root@k8s-master1 ~]# kubectl cluster-info
Kubernetes master is running at https://10.0.0.63:6443
KubeDNS is running at https://10.0.0.63:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
#状态信息写入到文件:
kubectl cluster-info dump >a.txt
#kubectl describe pod [pod名]
#实时观察pod动态
kubectl get pods -w [删除创建pod,这条命令里都会输出出来,并可以显示整理流程]
https://www.cnblogs.com/superlinux/p/13160033.html
1. Flannel:
flannel有三种工作模式:1. vxlan(隧道方案) 2. host-gw(路由方案)2. udp(在用户态实现的数据封装解封装,由于性能较差已经被弃用)
vxlan模式:
vxlan模式会在当前服务器中创建一个cni0的网桥,和flannel.1隧道端点. 这个隧道端点会对数据包进行再次封装.然后flannel会把数据包传输到目标节点中.同时它也会在本地创建几个路由表.(可以通过命令 ip route 查看到)
[root@k8s-master1 ~]# ip route
default via 10.0.0.254 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.63
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
169.254.0.0/16 dev eth0 scope link metric 1002
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
1.1 Flannel网络部署与卸载:
1. 安装flannel网络:
wget https://www.chenleilei.net/soft/k8s/kube-flannel.yaml
kubectl apply -f kube-flannel.yaml
1.1 验证网络:
1.1.1 创建一个应用
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort
1.1.2 检查测试:
[root@k8s-master1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-f89759699-rcgh2 1/1 Running 0 52s 10.244.2.16 k8s-node2 <none> <none>
1.1.3 测试flannel网络连通性:
[root@k8s-master1 ~]# ping 10.244.2.16
PING 10.244.2.16 (10.244.2.16) 56(84) bytes of data.
64 bytes from 10.244.2.16: icmp_seq=1 ttl=63 time=0.865 ms
64 bytes from 10.244.2.16: icmp_seq=2 ttl=63 time=0.549 ms
1.1.4 卸载flannel网络:
[root@k8s-master1 ~]# ip route
default via 10.0.0.254 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.63
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink # <---flannel网络
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink # <---flannel网络
169.254.0.0/16 dev eth0 scope link metric 1002
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
[老师提供方法: 所有服务器执行]
ip link delete cni0
ip link delete flannel.1
执行后,检查ip route 查看是否有路由表,flannel网络已经不存在.
[root@k8s-master1 ~]# ip link delete cni0
Cannot find device "cni0"
[root@k8s-master1 ~]# ip link delete flannel.1
[root@k8s-master1 ~]# ip route
default via 10.0.0.254 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.63
169.254.0.0/16 dev eth0 scope link metric 1002
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
1.1.5 测试
[root@k8s-master1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-f89759699-rcgh2 1/1 Running 0 23m 10.244.2.16 k8s-node2 <none> <none>
[root@k8s-master1 ~]# ping 10.244.2.16
PING 10.244.2.16 (10.244.2.16) 56(84) bytes of data.
^C
--- 10.244.2.16 ping statistics ---
68 packets transmitted, 0 received, 100% packet loss, time 68199ms
此时,没有flannel网络的情况下,nginx的这个pod已经无法访问.
在卸载网络插件时无法删除可以使用 --grace-period=0 --force
如:
kubectl delete pod coredns-7ff77c879f-5cc29 -n kube-system --grace-period=0 --force
2. Calico网络部署与卸载
calico有2种中作模式:
1. ipip(隧道方案) 2.bgp(路由方案)
注意: 公有云可能会对路由方案造成影响,并且有的云主机会禁止路由(bgp)方案,所以有些云厂商是禁止此实现方式的,因为他会写入路由表,这样可能会影响到厂商现有网络.
路由方案: 对现有网络有一定的要求,但是他的性能最好,它是直接的路由转发模式,他不会经过数据包封装再封装,没有网络消耗.此方案优先选择,但是也要看厂商是否支持. 它会要求,二层网络可达
隧道方案: 对现有网络要求不高,它只需要三层通信正常基本都可以通信.
calico网络插件下载:
官方地址:
wget https://docs.projectcalico.org/manifests/calico.yaml
个人网盘地址:
wget https://www.chenleilei.net/soft/k8s/calico.yaml
注意: 安装calico网络插件 需要卸载 flannel网络插件.
#卸载flannel网络:
ip link delete cni0
ip link delete flannel.1
kubectl delete -f kube-flannel.yaml
#执行后,检查ip route 查看是否有路由表,flannel网络已经不存在.
[root@k8s-master1 ~]# ip link delete cni0
Cannot find device "cni0"
[root@k8s-master1 ~]# ip link delete flannel.1
[root@k8s-master1 ~]# ip route
default via 10.0.0.254 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.63
169.254.0.0/16 dev eth0 scope link metric 1002
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
calico配置:
1.默认网段修改:
找到以下内容:
# - name: CALICO_IPV4POOL_CIDR
# value: "192.168.0.0/16"
改为安装kubernetes时初始化的网段:
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
2. 安装calico网络插件 执行yaml
[root@k8s-master1 ~]# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
3. 卸载calico网络插件.
[root@k8s-master1 ~]# kubectl delete -f calico.yaml
检查;
kubectl get pods -o wide -n kube-system
2.1 验证与日志检查:
应用创建:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort
日志检查:
[root@k8s-master1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-f89759699-qlckm 1/1 Running 0 95s 10.244.169.130 k8s-node2 <none> <none>
[root@k8s-master1 ~]# curl -I 10.244.169.130
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Thu, 18 Jun 2020 12:41:58 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 May 2020 15:00:20 GMT
Connection: keep-alive
ETag: "5ecd2f04-264"
Accept-Ranges: bytes
[root@k8s-master1 ~]# kubectl logs nginx-f89759699-qlckm
10.244.36.64 - - [18/Jun/2020:12:47:09 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://10.0.0.65:32746/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36" "-"
访问没有问题,证明calico网络部署成功.
- 排查Pod卡在Terminating状态
概述
pod已经被删除,并且卡在Terminated状态较长时间,可能是因为:
- pod含有预期有关联的finalizer并且没有完成
- pod没有相应终止信号
排查手册
这个手册用于排查pod已经被删除,但长时间卡在Terminate状态,或者长于自己期望的时间。
当运行命令kubect get pods,你可以看到关于pod的输出:
NAME READY STATUS RESTARTS AGE
nginx-7ef9efa7cd-qasd2 1/1 Terminating 0 1h
初始步骤概述
1.收集信息
2.检查finalizers
3.检查节点状态
4.强制删除
详细步骤
1)收集信息
kubectl get pod -n [NAMESPACE] -p [POD_NAME] -o yaml
2)检查finalizers
首先检查一下是否有finalizers,如果有可能是无法完成的根本原因。
获取pod配置:
kubectlgetpod-n[NAMESPACE]-p[POD_NAME]-o yaml>/tmp/runbooks_pod_configuration.txt
并且检查metadata下面有finalizers,如果有则跳到 方案A)。
3)检查节点的状态信息
pod可能运行在因为某种原因发生故障的节点。
如果从/tmp/runbooks_pod_configuration.txt文件里面所指定的节点上所有的pod都卡在Terminated状态,那么极有可能是因为node节点故障导致的,可以通过运行命令检查:
kubectlgetnode[nodename]
4)删除pod
由于没有想用终止信号,pod可能不会终止,具体原因可能取决于程序的具体情况,常见原因可能包含:
- 用户控件代码紧密循环,不允许出现中断信号。
- 运行程序维护过程,例如:垃圾回收
这种情况可以跳转到 方案B
5)重启kubelet
如果没有其他效果,可以尝试在pod所在的节点上重启kubelet,查看 方案C
解决方案
A) 删除finalizer
B) 强制删除pod
C) 重启kubelet
A) 删除finalizers
删除pod的finalizers,运行命令:
kubectl patch pod[POD_NAME]-p'{"metadata":{"finalizers":null}}'
B) 强制删除pod
请注意,这是解决方法不是解决方案,请谨慎行事确保问题不会进一步恶化。另外请参与Statefulset有关的详细信息。
强制删除运行命令:
kubectldeletepod--grace-period=0--force--namespace[NAMESPACE][POD_NAME]
如果不生效,请重新参照排查手册,检查一下解决思路。
C) 重启kubelet
如果可以,SSH登陆到节点上重启kubelet进程,重启之前可以检查kubelet的日志是否有异常信息。
检查是否解决
如果kubectl get pod没有显示pod存在那么问题就得到了解决:
kubectlgetpod
进一步步骤
如果问题进一步出现,你可能需要:
- 检查终结器是否仍然需要完成
- 找到根本原因
检查终结器是否仍然需要完成
根据终结器需要完成的工作有所不同。
终结器未完成的常见情况包括
- Volume
2)确定根本原因
这将根据终结器的操作有所不同,并且需要特定的上下文知识。
可以检查kubelet的日志,可能会包含一些有用的信息。



1万+

被折叠的 条评论
为什么被折叠?



