Kubernetes核心
Kubernetes核心
kubernetes最小管理单元-Pod
- Pod是Kubernetes管理最小的基础单元。
- 一个Pod中封装了:
一个或者多个紧耦合的应用容器
存储资源
独立的IP
容器运行的选项
相同的Pod中的任何容器都将共享相同的名称空间和本地网络。容器可以很容易地与其他容器在相同的容器中进行通信。
Linux配置kubectl
1.配置好ECS弹性云服务器
2.将文件上传到home目录下
[root@ecs-k8s home]# tree /home/
/home/
├── kubeconfig.json
└── kubectl
3.安装kubectl
[root@ecs-k8s home]# cd /home
[root@ecs-k8s home]# chmod +x kubectl
[root@ecs-k8s home]# mv -f kubectl /usr/local/bin
[root@ecs-k8s home]# mkdir -p $HOME/.kube
[root@ecs-k8s home]# mv -f kubeconfig.json $HOME/.kube/config
4.根据使用场景,按需切换kubectl
的访问模式
● VPC网络内接入访问请执行此命令
[root@ecs-k8s home]# kubectl config use-context internal
● 互联网接入访问请执行此命令(需绑定公网apiserver地址)
[root@ecs-k8s home]# kubectl config use-context external
5.设置完成后,可以通过以下命令查看kubernetes集群信息
[root@ecs-k8s home]# kubectl cluster-info
Kubernetes master is running at https://192.168.0.225:5443
CoreDNS is running at https://192.168.0.225:5443/api/v1/namespaces/kube-system/services/coredns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
6.检查节点是否正常
[root@ecs-k8s home]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.0.126 Ready <none> 39m v1.17.17-r0-CCE21.8.1
192.168.0.252 Ready <none> 39m v1.17.17-r0-CCE21.8.1
实践1:Pod
1.POD定义文件的上传
通过winscp将下载的附件中的yml文件上传到客户端服务目录查看
2.创建POD
$ kubectl apply -f POD-1Container.yml
3.POD的管理
指定POD运行到指定的NODE上
$ kubectl apply -f POD-NodeSelector.yml
4.删除POD
$ kubectl get pod
$ kubectl delete pod nginx
上传一个Pod的yaml
# 编写一个Yaml文件
[root@ecs-k8s home]# cat POD-1Container.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80[root@ecs-k8s home]#
运行一个Pod
[root@ecs-k8s home]# kubectl apply -f POD-1Container.yml
pod/nginx unchanged
[root@ecs-k8s home]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 16m 172.16.0.51 192.168.0.126 <none> <none>
# 查看被调度的node节点
[root@ecs-k8s home]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 18m 172.16.0.51 192.168.0.126 <none> <none>
# 查看可以被调度的Node节点
[root@ecs-k8s home]# kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.0.126 Ready <none> 50m v1.17.17-r0-CCE21.8.1
192.168.0.252 Ready <none> 50m v1.17.17-r0-CCE21.8.1
# 给第一个节点打上 node=test 的标签。
[root@ecs-k8s home]# kubectl label nodes 192.168.0.252 node=mycontainer
node/192.168.0.252 labeled
# 删除node节点的标签
[root@ecs-k8s home]# kubectl label node 192.168.0.252 node-
有状态和无状态应用
无状态应用
- 无状态服务,易于部署而且易于扩展。如果流量上升,则只需要添加更多的负载均衡;上游容器镜像和基础架构中正在运行的容器几乎没有区别;可以随时替代,而且容器实例切换的过程几乎不需要耗费“切换成本”
有状态应用
- 有状态的服务,从部署开始,这些容器就开始与上有镜像不同了,时间越长它们的差异越大;每个运行的应用程序都至少有一个小状态(差异),但对于“无状态”应用程序来说,状态(差异)很小,而且可以进行快速替换。
无状态应用控制器
Replication Controller > ReplicaSets > Deployment
- Replication Controller : 只能保证Pod的数量在一个定值
- ReplicaSets: 除了完全继承RC 多了标签选择器的功能
- Deployment:继承以上功能,增加滚动更新(rolling update)和重新创建(recreate),默认为滚动更新。是如何具体创建Pod。
实践2:Deployment
1.创建deployment
[root@ecs-k8s home]# kubectl apply -f deployment.yaml
2.查看POD
[root@ecs-k8s home]# kubectl get pod
3.手动删除POD
[root@ecs-k8s home]# kubectl delete deployment nginx-deployment
4.扩展Deployment的数量
[root@ecs-k8s home]# kubectl scale deployment nginx-deployment --replicas=4
5.查看Deployment的状态
[root@ecs-k8s home]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 5s
实践3:StatefulSet
如果部署的应用满足右侧一个或者多个部署需求,则建议使用StatefulSet。
在具有以下特点时使用StatefulSet
稳定性,唯一的网络标识符
稳定性,持久化存储
有序的部署和扩展
有序的删除和终止
有序的自动滚动更新
1.创建StatefulSet
[root@ecs-k8s home]# kubectl apply -f statefulset.yml
2.查看StatefulSet
[root@ecs-k8s home]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5489c599c4-w99ms 1/1 Running 0 62s
web-0 1/1 Running 0 16s
web-1 1/1 Running 0 11s
[root@ecs-k8s home]#
[root@ecs-k8s home]#
[root@ecs-k8s home]# kubectl get statefulset
NAME READY AGE
web 2/2 24s
3.查看StatefulSet的yaml文件
[root@ecs-k8s home]# cat statefulset.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
实践4:DaemonSet
系统应用控制器-DaemonSet
DaemonSet能够让所有或者特定的Node节点运行一个Pod。当节点加入到Kubernetes集群中,Pod会被(DaemonSet)调度到该节点上运行。当节点从kubernetes集群中被移除,(DaemonSet)调度的Pod会被移除。
适合场景:
运行日志采集器在每个Node上,例如fluentd、logstash
每个Node上运行一个分布式存储的守护进程,例如glusterd、ceph
运行监控和的采集端在每个Node、例如prometheus、node、exporter、collectd等
在一个区域的Node上都运行一个守护进程
1.创建daemonset
[root@ecs-k8s home]# kubectl apply -f daemonset.yml
daemonset.apps/fluentd-elasticsearch created
2.查看kube-system的Daemonset
[root@ecs-k8s home]# kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
cceaddon-npd 2 2 2 2 2 <none> 49m
everest-csi-driver 2 2 2 2 2 <none> 49m
fluentd-elasticsearch 2 2 0 2 0 <none> 2m30s
icagent 2 2 2 2 2 <none> 48m
3.daemonset的yaml文件
[root@ecs-k8s home]# cat daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
实践5:Job
临时任务控制器-Job
我们经常需要进行批量数据处理和分析,以及按照实践进行调度执行。在Kubernetes中使用容器技术完成。使用Job和CronJob来执行。
Job负责批处理任务,即执行一次任务,它保证批处理任务一个或者多个Pod成功结束。
CronJob是基于调度的Job执行将会自动产生多个Job,调度格式参考Linux的cron系统。
1.Jobs创建和管理
[root@ecs-k8s home]# kubectl apply -f Job.yml
job.batch/pi created
2.查看Job运行状态
[root@ecs-k8s home]# kubectl get job
NAME COMPLETIONS DURATION AGE
pi 1/1 3m24s 3m24s
3.查看此Job的输出
[root@ecs-k8s home]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pi-d5gf4 0/1 computed 0 18m
web-0 1/1 Running 0 18m
web-1 1/1 Running 0 18m
[root@ecs-k8s home]# kubectl logs pi-d5gf4
4.查看Job的yaml文件
[root@ecs-k8s home]# cat Job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
实践6:Service
应用访问-Service
Service是Kubernetes最核心的概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求进行负载分发到后端的各个容器应用上。
Clusterip
: 默认类型,自动分配一个仅cluster内部可以访问的虚拟ipNodePort
: 在clusterip基础上为service在每台机器上绑定一个端口,这样就可以通过Nodeip:port方式来访问该服务Loadbalance
: 在NodePort基础上,接触cloud provider创建一个外部负载均衡器,并将请求转发到nodeip:portexternalName
: 把集群外部的服务引入到集群内部,在集群内中直接使用,没有任何类型的代理被创建
Service的创建和管理
1.创建deployment
[root@ecs-k8s home]# kubectl apply -f deployment.yml
deployment.apps/nginx-deployment created
[root@ecs-k8s home]# cat deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.12.2
ports:
- containerPort: 80
2.创建NodePort类型
[root@ecs-k8s home]# kubectl expose deployment nginx-deployment --type=NodePort
[root@ecs-k8s home]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.247.0.1 <none> 443/TCP 89m
nginx-deployment NodePort 10.247.32.170 <none> 80:31103/TCP 7s
3.通过curl命令查看验证网站
[root@ecs-k8s home]# curl 192.168.0.217:30621
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
实践:NameSpace
作用:
- Kubernetes可以使用NameSpace(命名空间)创建多个虚拟集群,NameSpace为名称提供一个范围。资源的Names在Namespace中具有唯一性
场景:
- 当团队或者项目中具有许多用户时候,可以考虑使用NameSpace来区分,a如果是少量用户集群,可以不需要考虑使用Namespace,如果需要它们提供特殊性质时,可以开始使用Namespace。
大多数的Kubernetes中的集群默认会有一个叫做default的namespace。实际上,应该是3个:
default
:你的service和app默认被创建于此。kube-system
:kubernetes系统组件使用。kube-public
:公共资源使用。
1.创建命名空间
[root@ecs-k8s home]# kubectl create namespace test
namespace/test created
[root@ecs-k8s home]# kubectl get namespace
NAME STATUS AGE
default Active 102m
kube-node-lease Active 103m
kube-public Active 103m
kube-system Active 103m
test Active 5s
2.创建一个 POD 并指定此 POD 运行在 test 命名空间
[root@ecs-k8s home]# kubectl apply -f POD-1Container.yml --namespace=test
[root@ecs-k8s home]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 15s
3.创建一个限制 CPU 和内存大小的 NameSpace
[root@ecs-k8s home]# kubectl create namespace quota-mem-cpu-example
namespace/quota-mem-cpu-example created
[root@ecs-k8s home]#
[root@ecs-k8s home]# kubectl get namespace
NAME STATUS AGE
default Active 106m
kube-node-lease Active 106m
kube-public Active 106m
kube-system Active 106m
quota-mem-cpu-example Active 8s
test Active 3m16s
4.创建 ResourceQuota 并和 NameSpace 进行关联。
# 使用resourceQuota关联命名空间管理资源限制大小
[root@ecs-k8s home]# kubectl create -f ns-cpu-mem.yml --namespace=quota-mem-cpu-example
resourcequota/mem-cpu-demo created
[root@ecs-k8s home]# cat ns-cpu-mem.yml
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-demo
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
5.查看resourcequota
[root@ecs-k8s home]# kubectl get resourcequota -n quota-mem-cpu-example
NAME CREATED AT
mem-cpu-demo 2021-09-29T02:48:28Z
添加限制
以上刚创建的 ResourceQuota 对象将在 quota-mem-cpu-example 名字空间中添加以下限
制:
每个容器必须设置内存请求(memory request),内存限额(memory limit),cpu 请求
(cpu request)和 cpu 限额(cpu limit)。
+ 所有容器的内存请求总额不得超过 1 GiB。
+ 所有容器的内存限额总额不得超过 2 GiB。
+ 所有容器的 CPU 请求总额不得超过 1 CPU。
+ 所有容器的 CPU 限额总额不得超过 2 CPU
1.创建POD 指定命名空间
[root@ecs-k8s home]# kubectl create -f quota-mem-cpu-pod.yml --namespace=quota-mem-cpu-example
pod/quota-mem-cpu-demo created
2.查看Pod是否正常运行
[root@ecs-k8s home]# kubectl get pod quota-mem-cpu-demo --namespace=quota-mem-cpu-example
NAME READY STATUS RESTARTS AGE
quota-mem-cpu-demo 1/1 Running 0 61s
3.使用第二个POD
[root@ecs-k8s home]# cat quota-mem-cpu-pod-2.yml
apiVersion: v1
kind: Pod
metadata:
name: quota-mem-cpu-demo-2
spec:
containers:
- name: quota-mem-cpu-demo-2-ctr
image: redis
resources:
limits:
memory: "1Gi"
cpu: "800m"
requests:
memory: "700Mi"
cpu: "400m"
4.查看报错
[root@ecs-k8s home]# kubectl apply -f quota-mem-cpu-pod-2.yml --namespace=quota-mem-cpu-example
Error from server (Forbidden): error when creating "quota-mem-cpu-pod-2.yml": pods "quota-mem-cpu-demo-2" is forbidden: exceeded quota: mem-cpu-demo, requested: requests.memory=700Mi, used: requests.memory=600Mi, limited: requests.memory=1Gi
# 以下命令输出显示第二个 Pod 并没有创建成功。错误信息说明了如果创建第二个 Pod,内存
请求总额将超出名字空间的内存请求配额。