一. 组件说明
master包含组件:
1. API SERVER: 所有服务访问统一入口
2. CrontrollerManager:维持pod副本期望数目
3. Scheduler:负责接收任务,选择合适的节点进行分配任务(pod)
4. ETCD:键值对数据库,储存k8s集群所有重要信息(持久化)
node包含组件:
5. Kubelet:直接跟容器引擎交互实现容器的生命周期管理。
6. Kube-Proxy:负责写入规则至IPTABLES、IPVS 实现服务映射访问。
其他:
7. COREDNS:可以为集群中的SVC创建一个域名与IP的对应关系解析
8. DASHBOARD:给k8s集群提供一个B/S结构访问体系
9. INGRESS CONTROLLER: 官方只能实现4层代理,INGRESS可以实现七层代理
10. FEDERATION: 提供一个可以跨集群中心的多k8s统一管理功能
11. PROMETHEUS: 提供一个k8s集群的监控能力
12. ELK:提供k8s集群日志统一分析接入平台
杂记:
查看容器运行情况:
pod运行在哪个节点,就在哪个节点查看 --> docker ps
13. pod说明:
只要运行pod,就会运行一个名为pause的容器
同一个pod内,多个容器共用pause容器的网络站,共用存储,容器间端口不能重复
14. 控制器
RC(replication controller):确保容器应用副本数始终保持在用户定义数量。--已淘汰
RS(replica set):跟RC功能一样,但支持集合式的selector,不支持滚动更新
Deployment支持滚动更新,但不负责pod创建,pod由RS创建;创建deployment控制器之后,会由deployment定义一个RS
15. HPA 水平自动扩展:自动增加或删除pod
16. kubectl命令自动补全:source <(kubectl completion bash)
--------------------------------------------------------------------------------
二. 安装前环境准备(master和node)
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
#关闭selinux
sed -ri 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
cat /etc/selinux/config
setenforce 0
getenforce
#关闭swapoff
sed -ri 's/.*swap.*/#&/' /etc/fstab #其中&代表前面匹配到的字符
cat /etc/fstab
swapoff -a
#添加hosts解析
cat /etc/hosts
cat >> /etc/hosts << EOF
192.168.80.105 k8smaster
192.168.80.106 k8snode
EOF
#config配置
cat > /etc/sysctl.d/kubernetes.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv6.conf.all.disable_ipv6 = 1
EOF
#启用config配置文件
sysctl -p /etc/sysctl.d/kubernetes.conf
#docker安装(安装前确认yum源已ok)
yum install -y docker-ce docker-ce-cli containerd.io --master和node节点都安装
--------------------------------------------------------------------------------
三. 安装
1. aliyun配置网站:https://developer.aliyun.com/mirror/kubernetes?spm=a2c6h.13651102.0.0.3e221b11wKGGFp
2. 配置kubelet/kubeadm/kubectl的yum源:
2.1 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
3. setenforce 0
4. yum install -y kubelet kubeadm kubectl
kubeadm config images list #可以列出安装所需的镜像列表
kubeadm config images pull #拉取镜像到本地
5. systemctl enable kubelet && systemctl start kubelet
ps: 由于官网未开放同步方式, 可能会有索引gpg检查失败的情况, 这时请用 yum install -y --nogpgcheck kubelet kubeadm kubectl 安装
6. yum list installed | grep kube --查询是否已安装kubeadm,kubelet,kubectl及其版本
kubeadm init phase preflight #安装前环境预检查
7. 部署kubernetes master节点
新版可直接执行:kubeadm init
kubeadm init --apiserver-advertise-address=192.168.80.105 --image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.22.3 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
warning:
[preflight] Running pre-flight checks
[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/
[WARNING FileExisting-tc]: tc not found in system path
[WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
错误关键信息总结:
Kubernetes version: v1.21.1,依赖/coredns/coredns:v1.8.0,registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0 不存在。
解决方案:
本地执行以下命令:
docker pull coredns/coredns:1.8.0 --手动下载镜像
docker tag coredns/coredns:1.8.0 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0 -tag重命名
8. master安装完后提示信息:
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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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.80.105:6443 --token u9356z.69lt89edxc7bpnq6 \
--discovery-token-ca-cert-hash sha256:6d4393386156f7c657f57845a1ecb40beb8aebbf1f0e745a162404e4c71ec18a
如果忘记token,执行如下命令打印
kubeadm token create --print-join-command
9. 网络配置
github官网查看:https://github.com/flannel-io/flannel
curl -o ./kube-flannel.yml https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
或wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
10. 注意:
node节点需下载proxy,flannel,pause镜像,避免对应容器无法开启
11. 阿里云镜像仓库地址
registry.aliyuncs.com/google_containers/
--------------------------------------------------------------------------------
四. 命令说明
kubectl --help
1. kubectl get pod/pods --查pod
2. kubectl get deployment --查控制器
3. kubectl get service --查看服务
4. kubectl get nodes --查看节点
5. kubectl delete deployment + 控制器名字 --删除控制器
6. kubectl delete pod + pod名字 --删除pod
7. kubectl delete service + service名字 --删除service
kubectl delete rs rs名 --删除rs
8. kubectl get namespace --查看命名空间
9. kubectl describe pods + pod名字 --查看pod详情(排错常用)
kubectl describe deployments #查看deployment控制器
10. kubectl logs -f + pods名 --查看日志(排错常用)
11. kubectl run --Create and run a particular image in a pod.
12. kubectl create & kubectl apply两个命令区别
kubectl create命令,是先删除所有现有的东西,重新根据yaml文件生成新的。所以要求yaml文件中的配置必须是完整的,较适合命令式编程使用,如rs
kubectl apply命令,根据配置文件里面列出来的内容,升级现有的。所以yaml文件的内容可以只写需要升级的属性,较适合申明式编程使用,如deployment
kubectl apply/create -f yml文件 --record #recored参数可以记录命令,可以很方便的查看每次revision的变化
13. ipvsadm -Ln
14. kubectl edit svc + service名 --修改service
kubectl edit pod + pod名 --编辑pod
15. kubectl explain pod --查看pod有哪些功能模块
kubectl explain pod.apiversion --查看具体模块
16. kubectl logs myapp-pod -c test --查看容器log,其中myapp-pod为pod名,-c指定容器名,故test为容器 (一般在一个pod中有多个容器时使用)
17. kubectl exec + pod名 -it -- /bin/sh --kubectl进入容器内部,其中 “--” 为固定格式,此为pod中只有一个容器情况下
kubectl exec + pod名 -c 容器名 -it -- '/bin/sh' --进入pod中的某个容器
18. kubectl scale deployment/deployment名 --replicas 3 --扩容副本数为3
kubectl scale deployment nginx-deployment --replicas 4 --扩容副本数为4,其中nginx-deploymnet为deployment名称
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80 #如果集群支持HPA,可设置自动扩展,cpu高于80%时扩容至15个,小于时缩减至10个pod
19. kubectl get pod -o wide --查看pod
20. kubectl get pod -n + 命名空间 --查看某个命名空间中的容器,命名空间:default/kube-node-lease/kube-public/kube-system
21. kubectl get pod --show-labels --查看pod标签
kubectl label pod pod名 tier=标签名 --修改pod标签
kubectl get endpoints
22.
k8s很多副本监控数是以标签为准
23. kubectl set image deployment/nginx-deployment nginx=nginx:v2
更新镜像,会创建一个新rs,旧rs也将保留
24. kubectl rollout undo deployment/nginx-deployment -- 回滚,回退至上一个镜像版本或rs,其中nginx-deployment为deployment控制器名称
kubectl rollout undo deployment/nginx-deployment --to-revision=2 #回滚至指定版本,此处为2版
kubetcl rollout status deployments nginx-deployment --查看回滚更新状态
kubectl rollout history deployment/nginx-deploment --查看回滚更新历史版本
kubectl rollout pause deployment/nginx-deployment #暂停deployment的更新
25. kubectl get cm +configmap名 --查看configmap
26. kubectl get pvc
kubectl get pv
kubectl get statefulset
kubectl get pv nfspv1 -o yaml #以yaml格式输出pv详细信息
kubectl edit pv nfspv1 #编辑pv
27. kubectl get node --show-labels --查看node节点标签
28. kubectl taint nodes k8snode01 checker=app:NoExecute #设置taint污点标签
kubectl taint nodes k8snode01 checker=app:NoExecute- #删除taint污点,末尾的“-”表示删除
29. dig nginx-nfs.default.svc.cluster.local @10.244.0.8 --statefulset使用headless服务来控制pod的域名,此为域名的FQDN
service名 namespace名 .svc.clusterlocal为固定格式 @DNSIP
clusterlocal为集群域名
30. kubectl api-resources #查看权限列表
--------------------------------------------------------------------------------
五. Label说明
Label Selector的表达式有两种:基于等式的(Equality-based)和基于集合的(Set-based)。
下面是基于等式的匹配例子:
name=redis-slave:匹配所有标签为name=redis-slave的资源对象。
env != production:匹配所有标签env不等于production的资源对象。
下面是基于集合的匹配例子
name in (redis-master, redis-slave):匹配所有标签为name=redis-master或者name=redis-slave的资源对象。
name not in (php-frontend):匹配所有标签name不等于php-frontend的资源对象。
还可以通过多个Label Selector表达式的组合实现复杂的条件选择,多个表达式之间用“,”进行分隔即可,几个条件之间是“AND”的关系,即同时满足多个条件,例如:
name=redis-slave, env!=production
name not in (php-frontend), env!=production
Pod中lebel定义在metada中:
apiVersion: v1
kind: Pod
metadata:
name: myweb
labels:
app: myweb
RC和Service在spec中定义Selector与Pod进行关联:
RC:
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 1
selector:
app: myweb
template:
…………
Service:
apiVersion: v1
kind: Service
metadata:
name: Test
spec:
type: NodePort
selector:
app: myweb
ports:
- port: 80
nodePort: 30008
targetPort: 80
protocol: TCP
Deployment、ReplicaSet、DaemonSet和Job则可以在Selector中使用基于集合的筛选条件:
selector:
matchLabels:
app: myweb
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
- {key: environment, operator: NotIn, values: [dev]}
matchLabels用于定义一组Label,与直接写在Selector中作用相同;matchExpressions用于定义一组基于集合的筛选条件,可用的条件运算符包括:In、NotIn、Exists和DoesNotExist。
如果同时设置了matchLabels和matchExpressions,则两组条件为“AND”关系,即所有条件需要同时满足才能完成Selector的筛选
--------------------------------------------------------------------------------
六. Replica Set
Replica Set支持基于集合的Label selector(Set-based selector),而RC只支持基于等式的Label selector(equality-based selector),所以Replica Set的功能更强大。
RS例子:
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: frontend
spec:
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
…………
Replica Set很少单独使用,它主要被Deployment这个更高层的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。
RC和RS的特性与作用如下:
-在大多情况下,我们通过定义一个RC实现Pod的创建过程及副本数量的自动控制。
-RC里包括完整的Pod定义模板。
-RC通过Label Selector机制实现对Pod副本的自动控制。
-通过改变RC里的Pod副本数量,可以实现Pod的扩容或缩容功能。
-通过改变RC里Pod模板中的镜像版本,可以实现Pod的滚动升级功能。
--------------------------------------------------------------------------------
七. Deployment
Deployment相对于RC的最大区别是我们可以随时知道当前Pod“部署”的进度。
创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程。
定义例子:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
containers:
- name: tomcat-demo
image: tomcat
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
可以通过命令kubectl get deployment来查看Deployment的信息,其中的几个参数解释如下:
> DESIRED::Pod副本数量的期望值,即Deployment里定义的Replica。
> CURRENT:当前Replica的值,如果小于DESIRED的期望值,会创建新的Pod,直到达成DESIRED为止。
> UP-TO-DATE:最新版本的Pod的副本数量,用于指示在滚动升级的过程中,有多少个Pod副本已经成功升级。
> AVAILABLE:当前集群中可用的Pod副本数量,即集群中当前存活的Pod数量。
--------------------------------------------------------------------------------
八. service
1. 客户端访问pod流程(iptables代理版,目前由ipvs替代):
* 监听服务和端点由apiserver完成,通过kube-proxy监控;kube-proxy负责监控对应到的pod,及其匹配到的信息,并写入到iptables规则中。
* 客户端访问svc时,其实是访问的iptables规则,导向到后端pod对应的地址信息。
* 客户端访问pod是通过iptables实现的,iptables的规则是通过kube-proxy写入。
* apiserver通过监控kube-proxy以发现services和endpoints
* kube-proxy通过pod的labels(标签)信息判断此pod是否已写入到svc的端点信息里面
2. 一组pod可以对应到多个svc
3. 定义service
apiVersion: v1 #创建该对象所使用kubernetes api版本
kind: Service #创建对象的类别
metadata: #唯一性标识对象的一些数据
name: showdoc #service名称,同一个namespace中必须唯一
namespace: default #service所在命名空间
labels: #service的label
app: showdoc
sepc:
type: NodePort #service暴露端口类型,一般有clusterIP/NodePort/LoadBalance
ports:
- port: 80 #service的端口
targetPort: 80 #目标端口,containerPort:80
selector: #定义标签选择器,本例匹配statefulset的labels
app: showdoc
三个端口(port/nodeport/targetport)说明:
port和nodePort都是service的端口,前者暴露给集群内客户访问服务,后者暴露给集群外客户访问服务。
从这两个端口到来的数据都需要经过反向代理kube-proxy流入后端pod的targetPort,从而到达pod上的容器内。
4. ingress
官网:https://kubernetes.github.io/ingress-nginx/
定义ingress:
apiVersion: apps/v1 #该对象所使用的kubernetes api版本
kind: Ingress #创建对象的类别
metadata:
name: showdoc #该对象名称
namespace: default #该对象所属命名空间
annotations: #注解
kubernetes.io/ingress.class: nginx #声明使用的ingress控制器
spec:
rules:
- hosts: showdoc.example.com #服务的域名
http:
paths:
- path: / #路由路径
backend: #后端service
serviceName: showdoc #对应service的名称
servicePort: 80 #对应service的端口
--------------------------------------------------------------------------------
九. Volume(存储卷)
1.emptyDir
emptyDir是在Pod分配到Node时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,它是Kubernetes自动分配的一个目录,当Pod从Node上移除时,emptyDir中的数据也会被永久删除。
emptyDir的用途如下:
> 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保存。
> 长时间任务的中间过程CheckPoint的临时保存目录。
> 一个容器需要从另一个容器中获取数据的目录(多容器共享目录),同一个Pod中共享。
定义举例:
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
volumes:
- name: datavol
emptyDir: {}
containers:
- name: tomcat-demo
image: tomcat
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /mydata-data
name: datavol
2. hostPath
使用hostPath挂载宿主机上的文件或目录,主要用于以下几个方面:
> 容器应用程序生成的日志文件需要永久保存时,可以使用宿主机的文件系统存储。
> 需要访问宿主机上Docker引擎内部数据时,可以定义hostPath的宿主机目录为docker的数据存储目录,使容器内部应用可以直接访问docker的数据文件。
使用hostPath时,需要注意以下几点:
> 在不同的Node上的Pod挂载的是本地宿主机的目录,如果要想让不同的Node挂载相同的目录,则可以使用网络存储或分布式文件存储。
> 如果使用了资源配额管理,则Kubernetes无法将其在宿主机上使用的资源纳入管理。
hostPath的定义如下:
volumes:
- name: "persistent-storage"
hostPath:
path: "/data"
3.gcePersistentDisk
使用这种类型的Volume表示使用谷歌公有云提供的永久磁盘(Persistent Disk,PD)存放数据,
使用gcePersistentDisk有以下一些限制条件:
> Node需要是谷歌GCE云主机。
> 这些云主机需要与PD存在于相同的GCE项目和Zone中。
通过gcloud命令创建一个PD:
gcloud compute disks create --size=500GB --zone=us-centrall-a my-data-disk
定义gcePersistentDisk类型的Volume的示例如下:
volumes:
- name: test-volume
gcPersistentDisk:
pdName: my-data-disk
fsType: ext4
4.awsElasticBlockStore
与GCE类似,该类型的Volume使用亚马逊公有云提供的EBS Volume存储数据,需要先创建一个EBS Volume才能使用awsElasticBlockStore。
使用awsElasticBlockStore的一些限制条件如下:
> Node需要是AWS EC2实例。
> 这些AWS EC2实例需要与EBS volume存在于相同的region和availability-zone中。
> EBS只支持单个EC2实例mount一个volume。
通过aws ec2 create-volume命令创建一个EBS volume:
aws ec2 create-volume --availability-zone eu-west-la --size 10 --volume-type gp2
定义awsElasticBlockStore类型的Volume的示例如下:
volumes:
- name: test-volume
awsElasticBlockStore:
volumeID: aws://<availability-zone>/<volume-id>
fsType: ext4
5.NFS
使用NFS网络文件系统提供的共享目录存储数据时,我们需要在系统中部署一个NFS Server。
定义NFS类型的Volume的示例如下:
volumes:
- name: nfs-volume
nfs:
server: nfs-server.localhost
path: "/"
6.其他类型的Volume
iscsi:使用iSCSI存储设备上的目录挂载到Pod中。
flocker:使用Flocker来管理存储卷。
glusterfs:使用GlusterFS网络文件系统的目录挂载到Pod中。
rbd:使用Ceph块设备共享存储(Rados Block Device)挂载到Pod中。
gitRepo:通过挂载一个空目录,并从GIT库clone一个git repository以供Pod使用。
secret:一个secret volume用于为Pod提供加密的信息,可以将定义在Kubernetes中的secret直接挂载为文件让Pod访问。Secret volume是通过tmfs(内存文件系统)实现的,所以这种类型的volume不会持久化。
--------------------------------------------------------------------------------
十. PV/PVC (持久存储卷)
PV与Volume的区别如下:
> PV只能是网络存储,不属于任何Node,但可以在每个Node上访问。
> PV并不是定义在Pod上的,而是独立于Pod之外定义。
下面是NFS类型PV的yaml定义内容,声明了需要5G的存储空间:
apiVersion: v1
kind: PersistenVloume
metadata:
name: pv01
spec:
capacity:
storage: 5Gi
persistentVolumeReclaimPolicy: Recycle
accessMode:
- ReadWriteOnce
nfs:
path: /somepath
server: 192.168.80.108
PV的accessModes属性有以下类型:
> ReadWriteOnce:读写权限、并且只能被单个Node挂载。
> ReadOnlyMany:只读权限、允许被多个Node挂载。
> ReadWriteMany:读写权限、允许被多个Node挂载。
如果Pod想申请使用PV资源,则首先需要定义一个PersistentVolumeClaim(PVC)对象:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-01
spec:
accessMode:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
然后在Pod的volume定义中引用上述PVC即可:
volumes:
- name: mypd
persistentVolumeClaim:
claimName: pvc-01
PV是有状态的对象,它有以下几种状态:
> Available:空闲状态。
> Bound:已经绑定到某个PVC上。
> Released:对应的PVC已经删除,但资源还没有被集群收回。
> Failed:PV自动回收失败。
--------------------------------------------------------------------------------
十一. HPA
HPA有以下两种方式作为Pod负载的度量指标:
> CPUUtilizationPercentage
> 应用程序自定义的度量指标,比如服务在每秒内的相应的请求数(TPS或QPS)
CPUUtilizationPercentage是一个算术平均值,即目标Pod所有副本自带的CPU利用率的平均值。一个Pod自身的CPU利用率是该Pod当前CPU的使用量除以它的Pod Request的值,
比如我们定义一个Pod的Pod Request为0.4,而当前Pod的CPU使用量为0.2,则它的CPU使用率为50%,
HPA定义举例:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
maxReplicas: 10
minReplicas: 2
scaleTargetRef:
kind: Deployment
name: php-apache
targetCPUUtilizationPercentage: 90
除了通过yaml文件来定义HPA对象之外,还可以通过命令的方式创建:
kubectl autoscale deployment php-apache --namespace kube-example --cpu-percent=90 --min=1 --max=10
--------------------------------------------------------------------------------
十二. StatefulSet
StatefulSet有如下一些特性:
> StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。假设StatefulSet的名字叫kafka,那么第1个Pod叫kafka-0,第2个叫kafka-1,以此类推。
> StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态。
> StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数据的安全)。
StatefulSet除了要与PV卷捆绑使用以存储Pod的状态数据,还要与Headless Service配合使用,即在每个StatefulSet的定义中要声明它属于哪个Headless Service,
Headless Service与普通Service的区别在于,它没有Cluster IP,如果解析Headless Service的DNS域名,则返回的是该Service对应的全部Pod的Endpoint列表。
StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod实例创建了一个DNS域名,这个域名的格式为:
$(podname).$(headless service name)
比如一个3节点的kafka的StatefulSet集群,对应的Headless Service的名字为kafka,StatefulSet的名字为kafka,
则StatefulSet里面的3个Pod的DNS名称分别为kafka-0.kafka、kafka-1.kafka、kafka-3.kafka,
定义举例:
#定义statefulset
apiVersion: apps/v1 #创建该对象所使用的kubernetes api的版本
kind: StatefulSet #想要创建对象的类别
metadata: #帮助唯一性标识对象的一些数据,包括一个name字符串、UID和可选的namespace
name: showdoc #想要创建的对象名字,同一个namespace中必须唯一
namespace: default #想要创建的对象所在的命名空间
labels: #想要创建对象的标签
app: showdoc #标签
spec: #对象规格,指定资源的内容
serviceName: showdoc #对象名称
replicas: 2 #对象副本数
selector: #便签选择器,用于匹配pod的标签
matchLabels:
app: showdoc
template: #定义pod
metadata: #pod的label
labels:
app: showdoc
spec: #指定该资源的内容
terminationGracePeriodSeconds: 180
iniContainers: #定义初始化容器
- name: init #初始化容器名称
image: busybox:v1 #指定使用image及其版本
command: ["/bin/sh","-c","chmod","777","-R","/var/www"] #启动容器运行的命令,将覆盖容器中的entrypoint,对应docker中的entrypoint
imagePullPolicy: IfNotPresent #镜像拉取策略,有三个选项:always每次都从线上拉取;never只检查本地是否有对应镜像;ifnotpresent表示如果本地有就用本地的,没有就从线上拉取
volumeMounts: #设置挂载持久卷信息
- name: volume #挂载设备的名字,要与volumeclaimtemplate中定义name一致
mountPath: /var/www/html #挂载到容器中的目录
containers: #业务容器
- name: showdoc #容器名称
image: nginx:v1 #容器使用镜像及版本
imagePullPolicy: IfNotPresent #镜像拉取策略
ports:
- containerPort: 80 #容器对外开放端口
name: port #端口名称
volumeMounts:
- name: volume #挂载持久存储卷
mountPath: /var/www/html #容器内持久存储卷挂载路径
volumeClaimTemplate: #持久化存储模板,使用存储类
- metadata: #定义唯一性标识对象的一些数据
name: volume #定义一个挂载设备的名字,为volumemounts提供name
spec:
accessModes: ["ReadWriteOnce"] #挂载存储的读写模式
storageClassName: nfs #存储的名字
resources: #存储资源
requests:
storage: 50Gi #存储资源的空间大小
--------------------------------------------------------------------------------
十三 .私有云harbor配置
1. vim /etc/docker/daemon.json添加如下命令,然后重启docker
{
"insecure-registries": ["http://hub.atguigu.com"] --域名需按实际harbor调整
}
2. 加载docker-compose
3. 加载harbor安装包
github+jenkins+harbor+docker+k8s
--------------------------------------------------------------------------------
十四. Probe(探针)
探针是由 kubelet 对容器执行的定期诊断,可执行如下三种动作进行诊断:
> Exec:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
> TCPSocket:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
> HTTPGet:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
成功:容器通过了诊断。
失败:容器未通过诊断。
未知:诊断失败,因此不会采取任何行动。
1. readlinessProbe(就绪探针)
指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
举例1:
readinessProbe:
httpGet:
path: /test.heml
port: 80
initialDelaySeconds: 5 #kubelet在第一次执行探针之前要等待的时间,单位为秒
periodSeconds: 5 #探针执行的频率,此处为每隔10秒执行一次
举例2:
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 5
2. livenessProbe(存活探针)
指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
举例:
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
3. startupProbe(启动探针)
指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
--------------------------------------------------------------------------------
十五. 各种apiVersion含义
1. alpha
* 该软件可能包含错误。启用一个功能可能会导致bug
* 随时可能会丢弃对该功能的支持,恕不另行通知
2. beta
* 软件经过很好的测试。启用功能被认为是安全的。
* 默认情况下功能是开启的
* 细节可能会改变,但功能在后续版本不会被删除
3. stable
* 该版本名称命名方式:vX这里X是一个整数
* 稳定版本、放心使用
* 将出现在后续发布的软件版本中
4. v1
Kubernetes API的稳定版本,包含很多核心对象:pod、service等
5. apps/v1beta2
* 在kubernetes1.8版本中,新增加了apps/v1beta2的概念,apps/v1beta1同理
* DaemonSet,Deployment,ReplicaSet 和 StatefulSet的当时版本迁入apps/v1beta2,兼容原有的extensions/v1beta1
6. apps/v1
* 在kubernetes1.9版本中,引入apps/v1,deployment等资源从extensions/v1beta1, apps/v1beta1 和 apps/v1beta2迁入apps/v1,原来的v1beta1等被废弃。
* apps/v1代表:包含一些通用的应用层的api组合,如:Deployments, RollingUpdates, and ReplicaSets
7. batch/v1
* 代表job相关的api组合
* 在kubernetes1.8版本中,新增了batch/v1beta1,后CronJob 已经迁移到了 batch/v1beta1,然后再迁入batch/v1
8. autoscaling/v1
* 代表自动扩缩容的api组合,kubernetes1.8版本中引入。
* 这个组合中后续的alpha 和 beta版本将支持基于memory使用量、其他监控指标进行扩缩容
9. extensions/v1beta1
deployment等资源在1.6版本时放在这个版本中,后迁入到apps/v1beta2,再到apps/v1中统一管理
10. certificates.k8s.io/v1beta1
安全认证相关的api组合
11. authentication.k8s.io/v1
资源鉴权相关的api组合
----------------------------------------------------------------------------------------------------------------------------------------------------------------
CPU说明:
1cpu为1核心cpu
1cpu=1000m cpu
表达式 0.1 CPU 等价于表达式 100m cpu,可以看作 “100 millicpu”
在metrics-server中,获取某个节点的使用情况,cpu的单位有时是n (1m = 1000*1000n )
----------------------------------------------------------------------------------------------------------------------------------------------------------------
十六. Node隔离命令
隔离:
法一:kubectl patch node k8snode01 -p '{"spec":{"unschedulable":true}}'
法二:kubectl cordon k8snode01
解除隔离:
法一:kubectl patch node k8snode01 -p '{"spec":{"unschedulable":false}}'
法二:kubectl uncordn k8snode01
--------------------------------------------------------------------------------
十七. 服务质量 QoS
QoS 主要分为 Guaranteed、Burstable 和 Best-Effort三类,优先级从高到低.
1. Guaranteed(有保证的)
属于该级别的 Pod 有以下两种:
Pod 中的所有容器都且仅设置了 CPU 和内存的 limits
Pod 中的所有容器都设置了 CPU 和内存的 requests 和 limits ,且单个容器内的requests==limits(requests不等于0)
举例:(仅设置了 CPU 和内存的 limits)
containers:
- name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
- name: bar
resources:
limits:
cpu: 100m
memory: 100Mi
举例:(单个容器内的requests==limits)
containers:
- name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
requests:
cpu: 10m
memory: 1Gi
2.Burstable(不稳定的)
Pod 中只要有一个容器的 requests 和 limits 的设置不相同,那么该 Pod 的 QoS 即为 Burstable。
举例:(容器 foo 指定了 resource,而容器 bar 未指定)
containers:
- name: foo
resources:
limits:
cpu: 10m
memory: 1Gi
requests:
cpu: 10m
memory: 1Gi
- name: bar
举例:(容器 foo 设置了内存 limits,而容器 bar 设置了CPU limits)
containers:
- name: foo
resources:
limits:
memory: 1Gi
- name: bar
resources:
limits:
cpu: 100m
注意:如果容器指定了 requests 而未指定 limits,则 limits 的值等于节点资源的最大值,如果容器指定了 limits 而未指定 requests,则 requests 的值等于 limits。
3.Best-Effort(尽最大努力)
如果 Pod 中所有容器的 resources 均未设置 requests 与 limits,该 Pod 的 QoS 即为 Best-Effort
举例:
containers:
- name: foo
resources:
- name: bar
resources:
--------------------------------------------------------------------------------
十八. 资源回收
1. Kubernetes 通过 CGroup 给 Pod设置 QoS 级别,当资源不足时会优先 kill 掉优先级低的 Pod,通过 OOM 分数值来实现,OOM 分数值范围为 0-1000,OOM 分数值根据 OOM_ADJ参数计算得出。
2. 对于 Guaranteed 级别的 Pod,OOM_ADJ 参数设置成了-998,对于 Best-Effort 级别的 Pod,OOM_ADJ 参数设置成了1000,对于 Burstable 级别的 Pod,OOM_ADJ 参数取值从 2 到 999。
3. QoS Pods 被 kill 掉的场景和顺序如下所示:
> Best-Effort Pods:系统用完了全部内存时,该类型 Pods 会最先被 kill 掉
> Burstable Pods:系统用完了全部内存,且没有 Best-Effort 类型的容器可以被 kill 时,该类型的 Pods 会被 kill 掉
> Guaranteed Pods:系统用完了全部内存,且没有 Burstable 与 Best-Effort 类型的容器可以被 kill 时,该类型的 pods 会被 kill 掉
--------------------------------------------------------------------------------
十九. Security Context
Security Context,即安全上下文,用于定义Pod或Container的权限和访问控制。
Kubernetes 提供了三种配置 Security Context 的方法:
> Container-level Security Context:应用于容器级别
> Pod-level Security Context:应用于Pod级别
> Pod Security Policy:应用于集群级别
容器级别: 仅应用到指定的容器上,并且不会影响 Volume。
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec:
containers:
- name: hello-world-container
securityContext:
privileged: true
Pod级别: 应用到 Pod 内所有容器,会影响 Volume.
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec:
containers:
securityContext:
fsGroup: 1234
supplementalGroups: [5678]
seLinuxOptions:
level: "s0:c123,c456"
PSP:PSP 是集群级的 Pod 安全策略,自动为集群内的 Pod 和 Volume 设置 Security Context。
支持的控制项:
privileged 运行特权容器
defaultAddCapabilities 可添加到容器的 Capabilities
requiredDropCapabilities 会从容器中删除的 Capabilities
allowedCapabilities 允许使用的 Capabilities 列表
volumes 控制容器可以使用哪些 volume
hostNetwork 允许使用 host 网络
hostPorts 允许的 host 端口列表
hostPID 使用 host PID namespace
hostIPC 使用 host IPC namespace
seLinux SELinux Context
runAsUser user ID
supplementalGroups 允许的补充用户组
fsGroup volume FSGroup
readOnlyRootFilesystem 只读根文件系统
allowedHostPaths 允许 hostPath 插件使用的路径列表
allowedFlexVolumes 允许使用的 flexVolume 插件列表
allowPrivilegeEscalation 允许容器进程设置
defaultAllowPrivilegeEscalation 默认是否允许特权升级
RunAsUser:
MustRunAs - 必须配置一个 range。使用该范围内的第一个值作为默认值。验证是否不在配置的该范围内。
MustRunAsNonRoot - 要求提交的 Pod 具有非零 runAsUser 值,或在镜像中定义了 USER 环境变量。不提供默认值。
RunAsAny - 没有提供默认值。允许指定任何 runAsUser 。
--------------------------------------------------------------------------------
二十. 亲和性
1. 节点亲和性(书写时和containers平级),硬亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #硬策略
nodeSelectorTerms:
- matchExpressions:
- key: app
operator: In
values:
- zabbix
说明:
2. 容器反亲和性,软亲和
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 软策略
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- wordpress
说明:如果一个节点上面有 app=wordpress 这样的 Pod 的话,那么我们的 Pod 就尽可能别调度到这个节点上面来。
--------------------------------------------------------------------------------
二十一. 更新策略
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0