Kubernetes 概念描述

k8s 管理

– 前言

  • 主要是k8s核心概念的描述随笔…

1 命令行管理

  • kubectl 命令行管理工具
    • 管理应用程序生命周期
    • 远程连接k8s 集群

1.1 基础命令概要

类型命令描述
基础命令explain文档参考资料
-get-o wide 显示一个或多个资源
部署命令rollout管理资源的发布
-scale扩容或缩容Pod 数量
集群管理命令cluster-info显示集群信息
-certificate修改证书
-cordon标记节点不可调度
-uncordon标记节点可调度
-drain驱逐节点上的应用,准备维护下线
-taint修改节点taint 标记
故障诊断调试describe显示特定资源或资源组的详细信息
-logs在一个pod种打印一个容器日志。如果pod 只有一个容器,容器名可选
-exec执行命令到容器
高级命令apply通过文件名或标准输入对资源应用配置
-patch使用补丁修改,更新资源的字段
其他命令help所有命令帮助

1.2 基础命令举例

# 创建
kubectl run nginx --replacs=3 --image=nginx:1.14 --port=80
kubectl get pods,deploy

# 发布
kubectl expose deployment nginx --port=80 --type=NodePort --target-port=80 --name=nginx-service
kubectl get service


# 更新
kubectl set image deployment/nginx nginx:1.15

# 回滚
kubectl rollout history deployment/nginx
kubectl rollout undo deployment/nginx

# 删除
kubectl delete deployment/nginx
kubectl delete svc/nginx-service

1.3 kubectl 远程管理配置

1.3.1 生成访问的证书
[root@master01 k8s]# cat k8s_config.sh
#!/bin/bash

cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

# 设置集群参数
kubectl config set-cluster kubernetes \
  --server=https://10.199.204.181:6443 \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --kubeconfig=config

# 设置客户端认证参数
kubectl config set-credentials cluster-admin \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --client-key=admin-key.pem \
  --client-certificate=admin.pem \
  --kubeconfig=config

# 设置上下文参数
kubectl config set-context default \
  --cluster=kubernetes \
  --user=cluster-admin \
  --kubeconfig=config

# 设置默认上下文
kubectl config use-context default --kubeconfig=config

1.3.2 远程访问实现
# 认证文件+ kubectl 命令实现访问
kubectl --kubeconfig=./config get node

# home 目录创建 .kube 目录
kubectl  get node (直接访问)

2 yaml 配置文件使用

  • 通过文件来描述资源对象(留存复用)
    • 缩进表示层级关系
    • “#” 表示注释
    • “—” 表示一个yaml 开始
    #run 命令生成
    kubectl run --image=nginx my-deploy -o  yaml --dry-run > my-deploy.yaml
    
    # get 命令导出
    kubectl get my-deploy/nginx -o=yaml --export > my-deploy.yaml
    
    # Pod 字段帮助
    kubectl explain pods.spec.containers
    

3 Pod 进一步理解

3.1 Pod包含容器

  • Infrastructure Container: 基础容器
    • 维护整个Pod 网络空间
  • InitContainers: 初始化容器
    • 先于业务容器开始执行的容器
  • Containers: 业务容器
    • 并行启动
      docker ps 可以查看
      pause 基础容器 启动容器的基础模板
      
  • Pod 优势(共享网络,存储)
    • 两个应用之间发生文件交互
    • 通过127.0.0.1 或socket 实现通讯
    • 两个应用频繁调用

3.2 Pod 中容器拉去策略于状态

  • IfNotPresent:默认值,宿主机存在就不拉去镜像
  • Always: 每次创建Pod 都会重新拉取镜像
  • Never: Pod 永远不会主动拉去镜像
  • Pending, Running, Failed, Succeeded, Unknown
  • 自建harbor 镜像拉取(docker daemon.json 添加可信任)
    # 部署yaml 中添加凭据 
    imagePullSecrets:
      - name: myregistrykey
      
    # 主机查看认证信息
    cat .docker/config.json
    
    # 认证信息编码
     cat .docker/config.json | base64 -w 0
     
    # 创建凭据yaml 文件
    
    [root@node01 opt]# cat /root/.docker/registry-pull-secret.yml
      apiVersion: v1
      kind: Secret
      metadata:
        name: registry-pull-secret
      data:
        .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxMC4xOTkuMjA0LjE3NSI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZkMkZ1WkdGMmJUSXdNVGs9IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOC4wOS42IChsaW51eCkiCgl9Cn0=
      type: kubernetes.io/dockerconfigjson 
    
    # 查看信息
    kubectl get secret registry-pull-secret  --namespace=default  -o yaml
    
    # 不同 Namespace , secrets 可以同名
    # 在secrets创建后可以修改一些内容
    # 但不能修改Namespace。 所以,必须在创建时准确指定。
    

3.3 Pod 资源限制

  • Pod 与 Container 的资源请求和限制
    request:
      memory: "64Mi"
      cpu: "250m" # 一核cpu25%
    limits:
      memory: "128Mi"
      cpu: "500m"
    
    # 查看信息
    kubectl describe pod my-pod
    kubectl describe nodes 10.199.204.176
    

3.4 Pod 重启策略

  • restartPolicy (字段定义)
    • Always: 默认策略,容器退出,总是重启
    • OnFailure: 异常退出(状态码非0),重启(计划任务)
    • Never: 从不重启

3.5 Pod 健康检查

  • Probe 两种类型
    • livenessProbe(检查失败,根据规则操作)
    • readinessProbe (检查失败,k8s把Pod 从service endpoints 剔除)
  • Probe 三种检查方式
    • httpGet(发送http ,请求200-400表示成功)
    • exec(执行shell 状态码0 为成功)
    • tcpSocket(发去TCP Socket 建立成功)
      # kubectl get ep (service 通过 endpoint 管理后端IP)
      
      livenessProbe:
        exec:
          command:
          - cat
          - /tmp/healthy
        initialDeplaySeconds: 5
        periodSeconds: 5
        
      ---
        tcpSocket:
        port: 8080
        
      ---
        httpGet:
          path: /status
          port: 80
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      

3.5 Pod 调度约束

  • 同一个k8s 集群放在不同的位置满住部门或一些特殊场景要求
  • 创建流程
kubctl
APIserver
etcd
Scheduler
Kubelet
Docker
  • 创建完成 ,Pod 信息会记录在etcd 中,运行在那台主机,状态,便于查看
  • nodeName (指定Node 名称,跳过打分,指定部署)
  • nodeSelector (指定匹配Label 的Node 上)
    # 给几点打标签
    kubectl label nodes 10.199.204.176 env_role=dev
    # 查看标签
    kubectl get nodes --show-labels
    # 查看调度
    kubectl describe pod my-pod
    
    nodeName: 10.199.204.176
    
    ---
    nodeSelector:
      env_role: dev
    

3.6 故障排查

状态值描述
PendingPod 创建已经提交到kubernetes。但是,因为某种原因而不能顺利创建。例如:下载镜像失败,调度不成功
RunningPod 已经绑定到一个节点,并且已经创建了所有容器。至少有一个容器正在运行,或正在启动正在运行
SucceededPod 中所有容器都已经成功终止,不会重启
FailedPod 说有容器均已经终止,且至少有一个容器已经在故障中终止。要么容器非零退出,要么被系统终止
Unknown由于某种原因apiserver 无法获取Pod 的状态,通常是由于Master 与Pod 所在主机kubelet 通讯出现问题
# 常用命令
# 查看事件
kubectl describe TYPE/NAME
# 查看日志
kubectl logs TYPE/NAME [-c CONTINER]
# 进入容器中进行详细查看
kubectl exec -it POD [-c CONTINER] --COMMAND [args...]

4 k8s 控制器

  • Deployment (解决 “无状态” 应用落地而产生的)
  • StatefulSet (解决 “有状态” 应用落地而产生的)
  • DaemonSet (每个node里部署)
  • Job
  • CronJob

4.1 Deployment 使用

  • 标签与标签选择器的使用

  • 部署无状态应用

  • 管理Pod 和 ReplicaSet

    • 管理顺序

      Deployment
      ReplicaSet
      Pod
  • 部署,副本,升级,回滚

  • 声明式更新

  • web 服务,微服务使用

  • yaml 文件组成

    • 控制器定义
    • 控制器对象
      # yaml 模板生成
      kubectl create deployment nginx --image=nginx --dry-run -o yaml
      
      
      # 手动暴露服务(service 使用)
      kubectl expose --name=web deployment nginx --port=80 --target-port=8080 --type=NodePort
      
      # 查看
      kubectl get deployment,svc,pod
      
      # 模板实例
      [root@master01 opt]# cat nginx-pod.yaml
      apiVersion: v1
      kind: Deployment
      metadata:
        name: nginx
        namespace: default
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            imagePullSecrets:
            - name: registry-pull-secret
            containers:
            - name: nginx
              image: nginx
              ports:
              - conrainerPort: 80
      

4.2 Deployment 升级回滚,弹性伸缩

  • 默认滚动更新

    # 手动升级
    kubectl set image deployment/web  nginx:1.15
    
    
    #滚动更新 (创建新的rs 实现扩容,新老版本共存)
       - apply声明式更新,修改yaml 文件
    
    # 回滚指定版本
    kubectl rollout undo deployment/web --revision=2
    
    # 扩容
    kubectl scale deployment web --replicas=5
    

5 应用发布,实现外界连通

5.1 Service

5.1.1 存在的意义
  • 提供对外访问入口(实现负载均衡)
  • 动态感知后端pod (防止pod 失联)
    • CLusterIP (集群内部使用)
    • NodePort (集群外访问,通过nodeIP + 端口,同时也会有ClusterIP,四层负载均衡)
    • LoadBalancer (公有云,四层负载均衡)
  • 网络模式
    • iptables
    • IPVS
5.1.2 模板实例
  • 在api-server 的配置文件中指定service-cluster-IP + service-port 定义
    # 查看状态
    kubectl get svc,ep
    kubectl get pod -l app=nginx -o wide
    kubectl describe svc my-service
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      namespace: default
    spec:
      clusterIP: 10.0.0.1
      ports:
      - name: http
        port: 80
        protocol: TCP
        targetPort: 80
        nodePort: 30008
      selector:
        app: nginx
    
5.1.3 代理模式
  • kube-proxy 实现网络代理(kube-proxy 配置文件中配置)
    • iptables (用户态)

    • ipvs

      # 模块加载(centos7 默认加载)
      [rroot@node01 ~]# vim ipvs.sh
      #!/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
      
      # 查看是否加载
      lsmod | grep ip_vs
      
      # iptables
      # 查看所有规则 (至上而下的访问,非增量方式,匹配延时)
      iptables-save | grep 10.0.0.8
      
      
      #ipvs (内核态,四层转发LVS)
       ipvsadm -ln
       调度算法: rr, wrr, lc, wlc, ip hash
       配置文件中添加:(kube-proxy 配置文件中添加)
       --ipvs-scheduler=wrr
      
5.1.4 coreDNS 的意义
  • clusterIP 也是变化的, 通过解析固定访问方式。github 网址

  • DNS 服务监视Kubernetes API,为每一个Service 创建DNS 记录用于域名解析

    ClusterIP A my-svc.my-namespace.svc.cluster.local
    
  • coredns 配置的ip 与kubelet配置文件 配置相同

  • coredns 配置的domain 与kubelet配置文件 配置相同

    # 测试是否成功
    # 启动一个容器
    kubectl run -it --image=busybox:1.28.4 --rm --restart=Never sh
    
    # 容器内部测试
    / # nslookup kubernetes
    Server:    10.0.0.2
    Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
    
    # 跨命名空间
    nslookup my-service.default
    

5.2 Ingress

  • 全局负载均衡器(七层,四层 负载均衡)
  • Ingress Controller (控制器通过service想关联)
    • ingress-nginx
    • traefik
  • 修改使用主机网络:hostNetwork: true
Ingress
service
pod
  • ingress-nginx github 地址
  • ingress-nginx 所在节点配置解析
5.2.1 模板实例
# http
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  reules:
  - host: example.foo.com
    http:
      paths: /
      - backend:
        serviceName: service1
        servicePort: 80
# 查看实现方式
进入容器中
cat /etc/nginx/nginx.conf

# https
# 证书生成与secert创建
[root@master01 ssl]# cat self_certs.sh
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

cat > sslexample.foo.com-csr.json <<EOF
{
  "CN": "sslexample.foo.com",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes sslexample.foo.com-csr.json | cfssljson -bare sslexample.foo.com

#kubectl create secret tls sslexample-foo-com --cert=sslexample.foo.com.pem --key=sslexample.foo.com-key.pem

---
# 部署https
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
    - sslexample.foo.com
    secreName: testsecret-tls
  reules:
  - host: example.foo.com
    http:
      paths: /
      - backend:
        serviceName: service1
        servicePort: 80
        

6 存储卷

  • vilume 的存在使得pod 漂移到任何节点数据的访问
    • 卷来源 (spec.volume)
    • 挂载点 (spec.containers.volumeMounts)

6.1 emptyDir

  • Pod 删除该卷也会被删除
  • Pod 中容器之间数据共享
apiversion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: write
    image: centos
    command: ["bash","-c","for i in {1..10};do echo $i >> /data/hello;sleep 1;done"]
    volumeMounts:
      - name: data
        mountPath: /data
        
  - name: read
    image: centos
    command: ["bash", "-c", "tail -f /data/hello"]
    volumeMounts:
      - name: data
        mountPath: /data
 
  volumes:
  - name: data
    emptyDir: {}

6.2 hostPath

  • 挂载Node 文件系统上文件或者目录到Pod 中的容器
  • Pod 访问容器需要访问宿主机文件
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  contrainers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 36000
    volumeMounts:
    - name: data
      mountPath: /data
  vilumes:
  - name: data
    hostPath:
      path: /tmp
      type: Directory

6.3 NFS 网络挂载

apiVersion: apps/v1neta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMount:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot
        nfs:
          srver: 10.199.204.177
          path: /data/nfs

7 RBAC 简单实例

#授权apiserver 可以查看日志

[root@master01 opt]# more apiserver-to-kubelet-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
      - pods/log
    verbs:
      - "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kubernetes

8 上线准备

  • 了解业务架构
  • 需要的服务分类,有状态,无状态
  • 服务之间调用关系,通讯方式
  • 资源预估,下线上线
  • namespace 进行租户的隔离
  • 发布方式,如何外部访问
  • 项目基础镜像构建
  • yaml 文件编写部署

8.1 Tips

# 拉去私有仓库需要创建认证信息:

kubectl create secret docker-registry registry-pull-secret --docker-username=joker --docker-password=joker --docker-email=joker@joker.com  --docker-server=registry.docker.com -n joker

# yaml 中的配置
imagePullSecrets:
  - name: registry-pull-secret

# 数据库部署 StatefulSet
clusterIP: None (直接访问减少网络转发)

# 不同namespace 访问
db-0.mysql.default (pod + service + namespace 可以访问)

8.2 资源监控

  • 集群监控
    • 节点资源利用率
    • 节点数
    • 运行Pods
  • Pod 监控
    • Kubernetes 指标
    • 容器指标
    • 应用程序
  • 日志监控
    • k8s 系统的组件日志
    • k8s cluster 里面部署的应用程序日志
      • 标准输出
      • 日志文件
8.2.1 docker 对日志接管
  • 标准输出stdout (通过docker logs 可以查看)
    • 通过守护进程读取 /var/log/containers/ID.json
  • 存储的docker 中(随着容器的消亡,而消亡)
8.2.2 k8s 管理日志方案
  • ELK 方案使用
  • graylog 日志系统
8.2.2.1 方案一Node 部署日志收集程序
  • 应用无入侵,不支持多行,容器内日志需要挂载
  • DaemonSet 方式部署日志收集程序
    • /var/lib/kubelet/pods/ID*/volumes/kubernetes.io~empty-dir/ (emptyDir挂载空卷)
    • /var/lib/docker/containers/*/ *json.log
    • Pod 中容器日志目录挂载到宿主机统一目录 (hostPath)
      • 日志覆盖问题(开发根据容器名称命名日志文件)
8.2.2.2 方案二Pod 附加专用日志收集程序
  • 增加资源消耗,手动打标签日志源
  • 使用emptyDir 共享日志目录
  • 日志收集程序进行收集
8.2.2.3 方案二应用直接推送日志
  • 应用入侵,需要开发配合
  • 脱离k8s
8.2.3 filebeat 配置方案(直接连接ES)
  • 处理器使用自动添加k8s 属性
  • 日志路径 (* 递归匹配log 文件)
    • 标准输出(/var/lib/docker/containers hostPath 实现)
  • 格式化日志(正则匹配,logstash 优先)
  • 日志源(标记那个应用,动态获取)
    • 容器
    • 命名空间
    • service
    • 项目
8.2.4 kibana 配置
  • 索引模式创建(时间搓筛选)
  • discover 查看日志
  • 日志量过大,加logstash过滤, 进行有用的日志进行入库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值