概述
这篇文章是记录k8s的一些小知识点,涵盖一些操作配置等等,是对平时问题的一些小记录。
1. 命名空间与 Node 绑定
实际部署中,有时候会希望将某一个特定的命名空间下的 pod 都部署在指定的同一个节点,这里就涉及到了 PodNodeSelector
,它 允许 Pod 强制在特定标签的节点上运行,它的控制器行为如下:
- 如果
Namespace
的注解带有键scheduler.alpha.kubernetes.io/node-selector
, 则将其值用作节点选择算符。 - 如果名字空间缺少此类注解,则使用
PodNodeSelector
插件配置文件中定义的clusterDefaultNodeSelector
作为节点选择算符。 - 评估 Pod 节点选择算符和名字空间节点选择算符是否存在冲突。存在冲突将导致拒绝。
- 评估 Pod 节点选择算符和特定于名字空间的被允许的选择算符所定义的插件配置文件是否存在冲突。 存在冲突将导致拒绝。
如果我们希望将 pod 部署到某个节点,我们可以给该 pod 增加 nodeSelector
配置,值可以是节点名称,也可以是 label,同样,如果希望某个命名空间下的所有 pod 都部署到某个节点,我们只需要让 pod 创建的时候自动带上配置 nodeSelector
即可。
操作
-
修改 kubeapi 配置文件
/etc/kubernetes/manifests/kube-apiserver.yaml
,--enable-admission-plugins
增加PodNodeSelector
,如下:--enable-admission-plugins=NodeRestriction,PodNodeSelector
重启 kubelet
systemctl daemon-reload systemctl restart kubelet
-
编辑命名空间,增加
scheduler.alpha.kubernetes.io/node-selector
注解,值可以是指定节点的名称,也可以是 label,如下:-
编辑命名空间
kubectl edit namespace devops
-
增加注解,此处我加了一个 label
usefulness=devops
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: Namespace metadata: annotations: scheduler.alpha.kubernetes.io/node-selector: usefulness=devops creationTimestamp: "2021-12-04T09:39:36Z" finalizers: - finalizers.kubesphere.io/namespaces labels: kubernetes.io/metadata.name: devops kubesphere.io/namespace: devops name: devops resourceVersion: "69106" uid: 1c1c6f06-a491-49b9-9dcc-7458e1d590f1 spec: finalizers: - kubernetes status: phase: Active
-
-
为节点增加指定的label,如下:
root@master:~/k8s# kubectl label node node1 usefulness=devops node/node1 labeled root@master:~/k8s# kubectl describe node node1 Name: node1 Roles: worker Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/arch=amd64 kubernetes.io/hostname=node1 kubernetes.io/os=linux node-role.kubernetes.io/worker= usefulness=devops Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 ..........
经过上面三个步骤,现在该命名空间下新创建的 pod 都会自动带上 nodeSelector
配置了。
测试
这里我们测试在该命名空间下创建一个 nginx 应用,yaml 文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: devops
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
创建 deployment
root@master:~/k8s# kubectl apply -f nginx.yaml
deployment.apps/nginx-deployment created
这个时候我们观察下对应的 pod 的信息:
root@master:~/k8s# kubectl get pod -n devops -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-66b6c48dd5-b8qhd 1/1 Running 0 84s 10.233.90.10 node1 <none> <none>
nginx-deployment-66b6c48dd5-ll7pl 1/1 Running 0 84s 10.233.90.9 node1 <none> <none>
root@master:~/k8s# kubectl describe pod nginx-deployment-66b6c48dd5-b8qhd -n devops
Name: nginx-deployment-66b6c48dd5-b8qhd
Namespace: devops
Priority: 0
Node: node1/192.168.1.101
.....
QoS Class: BestEffort
Node-Selectors: usefulness=devops
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
.....
注意看该 pod 已经部署在了节点 node1 上,并且 pod 的信息中有这么一栏,这就是创建 pod 时自动带上的注解:
Node-Selectors: usefulness=devops
这个时候我们查看 pod 的 yaml 配置,可以看到该 yaml 文件 spec 下自动多了一个配置,如下:
root@master:~/k8s# kubectl get pod nginx-deployment-66b6c48dd5-b8qhd -n devops -o yaml
apiVersion: v1
kind: Pod
metadata:
.....
spec:
.....
nodeSelector:
usefulness: devops
.....
至此,该命名空间下的所有 pod 都会自动部署到 节点 node1 上。
2. 修改 NodePort 端口范围
默认情况下,NodePort 的端口范围是 30000-32767,但是有时候我们希望使用范围之外的节点端口,比如 80 和 443,这个时候我们仅需要修改 kube-apiserver 的对应配置 --service-node-port-range
即可,如果没有该项,手动添加一个即可,如下:
root@master:~/k8s# cat /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.1.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.1.100
- --allow-privileged=true
- --audit-log-maxage=30
- --audit-log-maxbackup=10
- --audit-log-maxsize=100
- --authorization-mode=Node,RBAC
- --bind-address=0.0.0.0
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction,PodNodeSelector
.....
- --service-node-port-range=1-32767
.....
之后重启 kubelet
systemctl daemon-reload
systemctl restart kubelet
这里需要注意两点:
- 对于已经创建的NodePort类型的Service,需要删除重新创建
- 如果集群有多个 Master 节点,需要逐个修改每个节点上的
/etc/kubernetes/manifests/kube-apiserver.yaml
文件,并重启 kubelet。