1.K8S简单诉述

• Kubernetes是Google在2014年开源的一个容器集群管理系统,Kubernetes简称K8S。

• Kubernetes用于容器化应用程序的部署,扩展和管理,目标是让部署容器化应用简单高效。

官方网站:http://www.kubernetes.io       官方文档:https://kubernetes.io/zh/docs/home  重点看概念和任务

2.K8S架构和组件

Master组件

kube-apiserver:Kubernetes API,集群的统一入口,各组件协调者,以RESTful API提供接口服务,所有对象资源的增删改查和监听操作都交给 APIServer处理后再提交给Etcd存储。 

kube-controller-manager:处理集群中常规后台任务,一个资源对应一个控制器,而 ControllerManager就是负责管理这些控制器的。例如 Deployment、Service

kube-scheduler :根据调度算法为新创建的Pod选择一个Node节点,可以任意部署, 可以部署在同一个节点上,也可以部署在不同的节点上。

etcd:分布式键值存储系统。用于保存集群状态数据,比如Pod、Service 等对象信息。

Node组件

kubelet :kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周 期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态 等工作。kubelet将每个Pod转换成一组容器。

kube-proxy :在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。

第三方容器引擎,例如docker、containerd、podman 容器引擎,运行容器。

3.K8S部署

kubeadm :Kubeadm是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。 部署地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/

二进制:从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。 下载地址:https://github.com/kubernetes/kubernetes/releases

第三方工具或者Web

安装链接:https://www.cnblogs.com/CGCong/p/15621946.html

4.K8S网络组件

部署网络组件的目的是打通Pod到Pod之间网络、Node与Pod之间网络,从而集群中数据包可以任意传输,形成了一 个扁平化网络。

主流网络组件有:Flannel、Calico等 而所谓的CNI( Container Network Interface,容器网络接口)就是k8s对接这些第三方网络组件的接口。

5.Kubeconfig配置文件

cat /root/.kube/config

其他节点使用这个配置文件也可以使用master的命令api,但它不是master.

拷贝这个config到其他节点,然后使用 kubectl --kubeconfig=/home/config get node

 也可以在家目录的同样路径下创建目录文件,--kubeconfig= 默认是/root/.kube/config

6.Kubectl命令行管理工具

https://kubernetes.io/zh/docs/reference/kubectl/overview/

 补全依赖包下载:yum install bash-completion    生效:source <(kubectl completion bash)  重启客户端

7.Kubectl快速部署应用

#使用Deployment控制器部署镜像:
kubectl create deployment cgcnginx --image=nginx
kubectl get deploy,pods
#使用Service将Pod暴露出去:
kubectl expose deployment cgcnginx --port=81 --type=NodePort --target-port=80 --name=cgcnginx
kubectl get service
#访问应用:
http://NodeIP:Port # 端口随机生成,通过get svc获取
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
cgcnginx     NodePort    10.110.220.181   <none>        81:30190/TCP   7m36s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        26h

--port=81  集群内部使用端口
--target-port=80  容器中应用端口
--type=NodePort  类型

8.Kubectl基本资源

# 查看pod详情信息,主要多了Pod IP、所属节点
[root@k8s1 ~]# kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE    IP             NODE   NOMINATED NODE   READINESS GATES
cgcnginx-865d746c47-2mz74   1/1     Running   0          2d3h   10.244.219.6   k8s3   <none>           <none>
# 查看service关联的pod
[root@k8s1 ~]# kubectl get endpoints
NAME         ENDPOINTS            AGE
cgcnginx     10.244.219.6:80      2d2h
kubernetes   192.168.137.3:6443   3d5h
# 查看Pod标签
[root@k8s1 ~]# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS   AGE    LABELS
cgcnginx-865d746c47-2mz74   1/1     Running   0          2d3h   app=cgcnginx,pod-template-hash=865d746c47
# -o yaml将一个资源导出yaml格式(配置文件)
[root@k8s1 ~]# kubectl get service cgcnginx -o yaml |grep -A 2 selector
  selector:
    app: cgcnginx
  sessionAffinity: None

kubectl get pods -o wide # 查看pod详情信息,主要多了Pod IP、所属节点
kubectl get endpoints # 查看service关联的pod
kubectl get pods --show-labels # 查看Pod标签
kubectl get service cgcnginx -o yaml |grep -A 2 selector # -o yaml将一个资源导出yaml格式(配置文件)

命名空间(Namespace):

Kubernetes将资源对象逻辑上隔离,从而形成多个虚拟集群。

应用场景:

• 根据不同团队划分命名空间

• 根据项目划分命名空间

kubectl get namespace

• default:默认命名空间

• kube-system:K8s系统方面的命名空间

• kube-public:公开的命名空间,谁都可以访问,

• kube-node-lease:K8s内部命名空间

 

两种方法指定资源命名空间:

• 命令行加 -n

• yaml资源元数据里指定namespace字段

• 命令行加 -A 指所有namespace

[root@k8s1 ~]# kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-56b8f699d9-5tmdl   1/1     Running   0          2d5h
calico-node-5bnx8                          1/1     Running   0          3d5h
calico-node-8sx8p                          1/1     Running   0          3d5h
calico-node-jtms5                          1/1     Running   0          3d5h
coredns-545d6fc579-5ns65                   1/1     Running   0          2d5h
coredns-545d6fc579-72h4f                   1/1     Running   0          2d5h
etcd-k8s1                                  1/1     Running   0          3d5h
kube-apiserver-k8s1                        1/1     Running   0          3d5h
kube-controller-manager-k8s1               1/1     Running   0          2d8h
kube-proxy-46p76                           1/1     Running   0          3d5h
kube-proxy-88r8n                           1/1     Running   0          3d5h
kube-proxy-mr5zm                           1/1     Running   0          3d5h
kube-scheduler-k8s1                        1/1     Running   0          2d8h
[root@k8s1 ~]# kubectl logs calico-node-jtms5 -n kube-system
kubectl create namespacke a
kubectl create namespacke b
kubectl get pods -n a
kubectl get pods -n b
kubectl create deployment cgcnginx1 --image=nginx -n a
kubectl get pods -n a
kubectl get pods -A 所有命名空间下的pods
kubectl delete <资源类型> <资源名称> # 删除资源
kubectl api-resources #列出资源命令名称和缩写
kubectl api-resources |grep pod

9.查看资源集群状态

查看master组件状态:
kubectl get cs
查看node状态:
kubectl get node 
查看Apiserver代理的URL:
kubectl cluster-info
查看集群详细信息:
kubectl cluster-info dump
查看资源的详细:
kubectl describe <资源类型> <名称名称>
查看资源信息:
kubectl get <资源>  #-o wide,-o yame,

#执行时会提示错误:error: Metrics API not available
#这是因为这个命令需要由metric-server服务提供数据,而这个服务默认没 有安装,还需要手动部署下。
查看Node资源消耗:
kubectl top node
查看Pod资源消耗:
kubectl top pod 
监控集群资源利用率获取流程
#kubectl top -> apiserver -> metrics-server(pod) -> 所有节点kubelet(cadvisor指标接口) -> 所有容器资源利用率

10.metric-server部署

# wget https://github.com/kubernetes-sigs/metricsserver/releases/download/v0.3.7/components.yaml
# vi components.yaml
...
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP
- --kubelet-use-node-status-port
- --kubelet-insecure-tls
image: lizhenliang/metrics-server:v0.4.1
...

增加一个kubelet-insecure-tls参数,这个参数作用是告诉metrics-server不验证kubelet提供的https证书

# kubectl apply -f components.yaml
检查是否部署成功:
#kubectl get pods -n kube-system
#kubectl get apiservices |grep metrics
#kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes

使用:
#kubectl top nodes --use-protocol-buffers #去掉警告,不加也没关系
#kubectl top pods

11.K8s组件日志

Pod部署的组件:
#kubectl get pods -n kube-system
#kubectl logs metrics-server-84f9866fdf-9czxr -n kube-system   -f  #-f就是实时的
kubectl logs(获取容器标准输出的日志)-> apiserver -> kubelet -> docker(接管了容器标准输出并写到文件中持久化) -> 获取某个容器的日志 除了kubelet之外,其他的组件都是pod运行的,所以查看kubelet用 systemd守护进程管理的组件: journalctl
-u kubelet journalctl -u kubelet -r #-r参数表示反序输出,(从新到旧) 查看系统日志: /var/log/messages

容器标准输出在宿主机的路径:
/var/lib/docker/containers/<container-id>/<container-id>-json.log

日志文件,进入到终端日志目录查看:
kubectl exec -it <pod名称> -- bash 

12.k8s生命周期

 

1、使用Deployment控制器部署镜像
kubectl create deployment web --image=tomcat
kubectl get deployment,pods
2、使用Service发布Pod
kubectl expose deployment web --port=80 --type=NodePort --target-port=8080 --name=web
kubectl get service
deployment一般用yaml文件部署

部署:kubectl apply -f xxx.yaml
卸载:kubectl delete -f xxx.yaml YAML语法格式: • 缩进表示层级关系 • 不支持制表符“tab”缩进,使用空格缩进 • 通常开头缩进
2 个空格 • 字符符号后缩进 1 个空格,如冒号、逗号等 •“---” 表示YAML格式,一个文件的开始 • “#”注释

 

 • 用create命令生成
kubectl create deployment web2 --image=nginx --replicas=3 --dry-run=client -o yaml > deployment2.yaml
kubectl expose deployment web2 --port=80 --target-port=80 --type=NodePort  --dry-run=client -o yaml > service2.yaml

 • 用create命令生成
kubectl get deployment nginx -o yaml > my-deploy.yaml
kubectl get deployment nginx -o json> my-deploy.yaml

• Pod容器的字段拼写忘记了
kubectl explain pods.spec.containers
kubectl explain deployment

13.deployment

Deployment是最常用的K8s工作负载控制器(Workload Controllers), 是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。 其他控制器还有DaemonSet、StatefulSet等。

Deployment的主要功能:

• 管理Pod和ReplicaSet

• 具有上线部署、副本设定、滚动升级、回滚等功能

• 提供声明式更新,例如只更新一个新的Image 

应用场景:网站、API、微服务

部署镜像:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 3 # Pod副本预期数量
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web # Pod副本的标签
    spec:
      containers:
      - name: web2
        image: nginx:1.16

• kubectl apply -f xxx.yaml
• kubectl create deployment web --image=nginx:1.16 --replicas=3 
• kubectl get pods 

  java-demo-56d54df448-dmnn5
  deployment名称-RS名称-随机名(因为会有多个副本)

应用升级(更新镜像三种方式,自动触发滚动升级)
• kubectl apply -f xxx.yaml
• kubectl set image deployment/web web2=nginx:1.17
• kubectl edit deployment/web #使用系统编辑器打开
滚动升级:K8s对Pod升级的默认策略,通过使用新版本.Pod逐步更新旧版本Pod,实现零停机发布,用户无感知。

ReplicaSet控制器用途:
• Pod副本数量管理,不断对比当前Pod数量与期望Pod数量
• Deployment每次发布都会创建一个RS作为记录,用于实现回滚

 

滚动升级
在K8s中的实现:
• 1个Deployment 
• 2个ReplicaSet

第一次部署:3个副本
升级:
第一次扩容 将创建一个新的RS,副本数设置为1
第二次缩容 将旧的RS的副本数缩容为2
第三次扩容 将新的RS的副本数扩容为2
第四次缩容 将旧的RS的副本数缩容为1
第五次扩容 将新的RS的副本数扩容为3
第六次扩容 将旧的RS的副本数缩容为0
最后的结果,旧RS副本数为0,新RS副本数为3
一个RS维护了一个镜像版本。

水平扩缩容(启动多实例,提高并发)
• 修改yaml里replicas值,再apply
• kubectl scale deployment web --replicas=10 #replicas参数控制Pod副本数量

回滚(项目升级失败恢复到正常版本) #回滚是重新部署某一次部署时的状态,即当时版本所有配置
kubectl rollout history deployment/web # 查看历史发布版本 
kubectl rollout undo deployment/web # 回滚上一个版本 
kubectl rollout undo deployment/web --to-revision=2 # 回滚历史指定版本
$ kubectl get rs    #查看RS记录
NAME DESIRED CURRENT READY AGE
cgcnginx-865d746c47 1 1 1 5d22h
web-6979f7f654 4 4 4 62m
web-6d78cc8568 0 0 0 86m
$ kubectl rollout history deploy web   #版本对应RS记录
deployment.apps/web
REVISION CHANGE-CAUSE
3 <none>
4 <none>$ kubectl describe rs web-6979f7f654 |grep revision
deployment.kubernetes.io/revision: 4
deployment.kubernetes.io/revision-history: 2

项目下线:
#不能直接删除pod 不然replicas会自动重新拉起到指定副本数
kubectl delete deploy/web
kubectl delete svc/web
kubetcl delete -f xxx.yaml

14.pod

Pod是一个逻辑抽象概念,Kubernetes创建和管理的最小单元, 一个Pod由一个容器或多个容器组成。

Pod特点:• 一个Pod可以理解为是一个应用实例,提供服务      • Pod中容器始终部署在一个Node上       • Pod中容器共享网络、存储资源

Pod主要用法:

• 运行单个容器:最常见的用法,在这种情况下,可以将Pod看做是单 个容器的抽象封装

• 运行多个容器:边车模式(Sidecar) ,通过在Pod中定义专门容器, 来执行主业务容器需要的辅助工作,这样好处是将辅助功能同主业务 容器解耦,实现独立发布和能力重用。(日志收集、应用监控)

创建Pod.taml(共享网络):
kubectl run bs --image=busybox --dry-run=client -o yaml > pod.yaml
vi pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    run: nginx
spec:
  containers:
  # 主程序
  - name: container1
    image: nginx
  # 辅助程序(边车容器)
  - name: container2
    image: busybox
command: ["/bin/sh","-c","sleep 12h"] 创建Pod: kubectl apply
-f pod.yaml 或者使用命令:kubectl run nginx --image=nginx kubectl run busybox --image=busybox -- sleep 24h 查看Pod: kubectl get pods kubectl describe pod <Pod名称> 查看日志: kubectl logs <Pod名称> [-c CONTAINER] kubectl logs <Pod名称> [-c CONTAINER] -f 进入容器终端: kubectl exec <Pod名称> [-c CONTAINER] -- bash kubectl exec -it my-pod -c bs -- sh #进入bs,网络协议栈共享,打破net ns隔离,实际上除了nginx和bs外,还有pause镜像容器做网络共享 / # netstat -tlnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN - tcp 0 0 :::80 :::* LISTEN - 删除Pod: kubectl delete pod <Pod名称>
pause 负责Pod网络的容器镜像
创建Pod2.yaml(共享存储):
vi pod2.yaml

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginxpod
  name: pod-volume-web
spec:
  containers:
  # 辅助程序(边车容器)
  - image: busybox
    name: bs
    command: ["/bin/sh","-c","sleep 12h"]
    volumeMounts: # 数据卷挂载
    - name: log # 指定挂载的数据卷名称
      mountPath: /data # 数据卷挂载到容器中的路径 映射到下面的log数据卷
  # 主程序
  - image: nginx
    name: webpod
    volumeMounts:
    - name: log
      mountPath: /usr/share/nginx/html  #也是映射到下面的log数据卷
  volumes: # 定义数据卷
  - name: log # 数据卷名称,2个容器通过这个数据卷达到共享存储
    emptyDir: {} # 数据卷类型

15.Pod对象:重启策略+健康检查(应用自修复)

 重启策略(restartPolicy):

• Always:当容器终止退出后,总是重启容器,默认策略。                                      什么样的应用需要持续性运行?nginx、mysql、redis

• OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。                        什么样的应用周期性运行?数据库备份、巡检

• Never:当容器终止退出,从不重启容器。                                                             什么样的应用一次性运行(按需)?计算类的,数据离线处理

[root@k8s1 home]# kubectl get pods pod-web -o yaml | grep restart
  restartPolicy: Always
    restartCount: 1
    restartCount: 0

 健康检查有以下两种类型:

• livenessProbe(存活检查):如果检查失败,将杀死容器,根据Pod 的restartPolicy来操作。

• readinessProbe(就绪检查):如果检查失败,Kubernetes会把 Pod从service endpoints中剔除。

• startupProbe(启动检查):检查成功才由存活检查接手,用于保护 慢启动容器

 支持以下三种检查方法:

• httpGet:发送HTTP请求,返回200-400范围状态码为成功。

• exec:执行Shell命令返回状态码是0为成功。

• tcpSocket:发起TCP Socket建立成功。

示例:端口探测
apiVersion: v1
kind: Pod
metadata:
  name: probe-demo
spec:
  containers:
  - name: web
    image: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 30 #启动容器后多少秒健康检查
      periodSeconds: 10 #以后每间隔多少秒检查一次
    readinessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 30 
      periodSeconds: 10
注:livenessProbe与readinessProbe的配置参数一样

示例:执行Shell命令
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy

示例:HTTP请求    #以下检查的链接 http://IP:8080/healthz
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
          - name: Custom-Header
          value: Awesome

 Pod环境变量

创建 Pod 时,可以为其下的容器设置环境变量。

应用场景:

• 容器内应用程序获取Pod信息

• 容器内应用程序通过用户定义的变量改变默认行为

变量值几种定义方式:

• 自定义变量值

• 变量值从Pod属性获取

• 变量值从Secret、ConfigMap获取

apiVersion: v1
kind: Pod
metadata:
  name: pod-envars
spec:
  containers:
    - name: test
      image: busybox
      command: [ "sh", "-c", "sleep 36000"]
      env:
        # 变量值从Pod属性获取
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: ABC # 自定义变量值
          value: "123456"

 Init Container:顾名思义,用于初始化工作,执行完就结束,可以理解为一次性任务。

• 支持大部分应用容器配置,但不支持健康检查

• 优先应用容器执行

应用场景:

• 环境检查:例如确保应用容器依赖的服务启动后再启动应用容器

• 初始化配置:例如给应用容器准备配置文件

边车容器与初始容器最大区别?
边车容器:持续运行
初始容器:工作完成后就退出,退出才启动应用容器

共同特点:都辅助应用容器工作。

示例:部署一个web网站,网站程序没有打到镜像中,而是希望从代码
仓库中动态拉取放到应用容器中。
apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  initContainers:
  - name: download
    image: busybox
    command:
    - wget
    - "-O"
    - "/opt/index.html"
    - http://www.baidu.com
    volumeMounts:
    - name: wwwroot
      mountPath: "/opt"
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: wwwroot
      mountPath: /usr/share/nginx/html
  volumes:
  - name: wwwroot
    emptyDir: {}

Pod中会有这几种类型的容器:

• Infrastructure Container:基础容器 , 维护整个Pod网络空间

• InitContainers:初始化容器, 先于业务容器开始执行

• Containers:业务容器 ,并行启动

静态Pod
静态Pod特点:

• Pod由特定节点上的kubelet管理

• 不能使用控制器

• Pod名称标识当前节点名称

在kubelet配置文件启用静态Pod的参数:
vi /var/lib/kubelet/config.yaml
...
staticPodPath: /etc/kubernetes/manifests
...

注:将部署的pod yaml放到该目录会由kubelet自动创建。
posted on 2021-11-29 22:00  聪神carry  阅读(82)  评论(0)    收藏  举报