K8S核心概念

k8s有很多核心概念 先写几个

Deployment

Deployment负责创建和更新应用程序的实例 创建Deployment后k8s master将应用程序实例调度到集群中的各个节点上,如果托管实例的节点关闭或被删除,Deployment控制器会将该实例替换为集群中另一个节点上的实例。这提供了一种自我修复机制来解决机器故障维护问题 白话就是之前用docker能在单机下载应用程序 运行应用程序 这个Deployment就是用来管理一下docker的这套机制 比如现在有机器a机器b两台机器 这两台机器上都有docker 这时我们要是想使用docker部署应用程序就需要机器a操作一下机器b操作一下 这个就很麻烦 然后这个Deployment就帮我们做了这个事情 我只要给k8s配置好从节点 只需在主节点使用命令Deployment就会帮我们进行负载均衡的下载应用与运行应用

Pod

pod是一个逻辑主机 用来运行应用实例可以运行多个实例 与docker容器一样 与docerk容器不同的是 pod可以共享每个容器的资源比如共享存储、共享网络、运行信息等 可以理解为docker容器运行在pod上

Service

这个service是一个抽象的东西 创建service之后外网就可以访问pod了 可以配置多个pod 它还会给我做负载均衡、服务发现

这个service是通过标签把多个应用组成一起的

在这里插入图片描述

上面k8s一中有相关的命令 Service就会只有这个标签名字一样它就会认为你先把这一些程序做一个集群 当你使用它暴露给外网的端口访问时 它就会进行负载均衡

service的暴露方式

type类型如下:

ClusterIP(默认):在集群的内部IP上公开Service。这种类型使得Service只能从集群内访问。

NodePort:使用NAT在集群中每个选定Node的相同端口上公开Service。使用 <NodeIP>:<NodePort> 从集群外部访问Service。是ClusterIP的超集。

LoadBalancer:在当前云中创建一个外部负载均衡器(如果支持的话),并为Service分配一个固定的外部IP。是NodePort的超集。

ExternalName:通过返回带有该名称的CNAME记录,使用任意名称(由spec中的externalName指定)公开Service。不使用代理。

k8s中的资源
k8s中所有的内容都抽象为资源, 资源实例化之后,叫做对象,上面说的那些核心概念都是k8s中的资源。
k8s中有哪些资源

工作负载型资源(workload): Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet等等
服务发现及负载均衡型资源(ServiceDiscovery LoadBalance):  Service,Ingress等等
配置与存储型资源: Volume(存储卷),CSI(容器存储接口,可以扩展各种各样的第三方存储卷)
特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型),Secret(保存敏感数据),DownwardAPI(
把外部环境中的信息输出给容器)

以上这些资源都是配置在名称空间级别 


集群级资源:Namespace,Node,Role,ClusterRole,RoleBinding(角色绑定),ClusterRoleBinding(集群角色绑定) 
元数据型资源:HPA(Pod水平扩展),PodTemplate(Pod模板,用于让控制器创建Pod时使用的模板),LimitRange(用来定义硬件资源限制的)

资源清单

之前我们直接用命令创建deployment,pod,service这些资源,其实在k8s中,我们一般都会使用yaml格式的文件来创建符合我们预期期望的资源,这样的yaml文件我们一般称为资源清单

资源清单yaml的格式

apiVersion: group/apiversion  # 如果没有给定group名称,那么默认为croe,可以使用kubectl api-versions 获取当前k8s版本上所有的apiVersion版本信息(每个版本可能不同)
kind:       #资源类别
metadata:  #资源元数据
   name
   namespace  #k8s自身的namespace
   lables
   annotations   #主要目的是方便用户阅读查找
spec:期望的状态(disired state)
status:当前状态,本字段由kubernetes自身维护,用户不能去定义
#配置清单主要有五个一级字段,其中status字段用户不能定义,由k8s自身维护

使用资源清单yaml来创建k8s的资源对象
用yaml创建deployment资源的对象
我们可以用创建deployment的命令加上参数 --dry-run -o yaml 就可以输出这次部署的资源清单yaml

kubectl create deployment my-tomcat --image=tomcat:7.0.75-alpine --dry-run -o yaml

在这里插入图片描述

我们可以对上面的yaml适当的修改下保存为文件deployment-demo.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-tomcat-yaml
  name: my-tomcat-yaml  #修改deployment的名称
spec:
  replicas: 2  #修改pod副本为两个
  selector:
    matchLabels:
      app: my-tomcat-yaml
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-tomcat-yaml
    spec:
      containers:
      - image: tomcat:7.0.75-alpine
        name: tomcat
        resources: {}
status: {}

然后执行如下命令就可以用yaml文件来创建这次部署

kubectl apply -f deployment-demo.yaml 

在这里插入图片描述

用yaml创建service资源的对象

kubectl expose deployment my-tomcat --name=tomcat --port=8080 --type=NodePort --dry-run -o yaml

在这里插入图片描述

修改下上面yaml内容,保存为文件:service-demo.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: my-tomcat-yaml
  name: tomcat-service-yaml  #修改service名称
spec:
  ports:
  - port: 80  # service的虚拟ip对应的端口,在集群内网机器可以访问用service的虚拟ip加该端口号访问服务
    nodePort: 30001  # service在宿主机上映射的外网访问端口,端口范围必须在30000-32767之间
    protocol: TCP
    targetPort: 8080  # pod暴露的端口,一般与pod内部容器暴露的端口一致
  selector:
    app: my-tomcat-yaml
  type: NodePort
status:
  loadBalancer: {}

然后执行命令如下命令就可以用yaml文件来创建service

kubectl apply -f service-demo.yaml 

在这里插入图片描述

针对已有资源输出资源清单yaml
查看pod资源列表
在这里插入图片描述

将资源的配置以yaml的格式输出出来
#使用 -o 参数加yaml,可以将资源的配置以yaml的格式输出出来,也可以使用json,输出为json格式

kubectl get pod nginx-deploy-7db697dfbd-2qh7v -o yaml  

在这里插入图片描述

k8s两个高级特性

Volume

Volume指的是存储卷,包含可被Pod中容器访问的数据目录。容器中的文件在磁盘上是临时存放的,当容器崩溃时文件会丢失,同时无法在多个Pod中共享文件,通过使用存储卷可以解决这两个问题。

常用的存储卷有如下几种:

configMap:configMap卷提供了向Pod注入配置数据的方法。ConfigMap对象中存储的数据可以被configMap
类型的卷引用,然后被Pod中运行的容器化应用使用。
emptyDir:emptyDir卷可用于存储缓存数据。当Pod分派到某个Node上时,emptyDir卷会被创建,并且Po
d在该节点上运行期间,卷一直存在。当Pod被从节点上删除时emptyDir卷中的数据也会被永久删除。
hostPath:hostPath卷能将主机节点文件系统上的文件或目录挂载到你的Pod中。在Minikube中的主机指
的是Minikube所在虚拟机。
local:local卷所代表的是某个被挂载的本地存储设备,例如磁盘、分区或者目录。local卷只能用作静态
创建的持久卷,尚不支持动态配置。
nfs:nfs卷能将NFS(网络文件系统)挂载到你的Pod中。
persistentVolumeClaim:persistentVolumeClaim卷用来将持久卷(PersistentVolume)挂载到Pod中
。持久卷(PV)是集群中的一块存储,可以由管理员事先供应,或者使用存储类(Storage Class)
来动态供应,持久卷是集群资源类似于节点。

Ingress

通过K8S的Ingress资源可以实现类似Nginx的基于域名访问,从而实现Pod的负载均衡访问。

安装Ingress
进入页面https://github.com/kubernetes/ingress-nginx/blob/nginx-0.20.0/deploy/mandatory.yaml,将里面内容复制,保存到k8s master机器上的一个文件ingress-controller.yaml里,里面的镜像地址需要修改下,大家直接用我下面这个yaml的内容

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      hostNetwork: true
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: siriuszg/nginx-ingress-controller:0.20.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 33
            runAsUser: 33
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10

---
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  #type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
  - name: https
    port: 443
    targetPort: 443
    protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

安装ingress,执行如下命令

kubectl apply -f ingress-controller.yaml 

查看是否安装成功

kubectl get pods -n ingress-nginx -o wide

在这里插入图片描述

配置ingress访问规则(就是类似配置nginx的代理转发配置),让ingress将域名tomcat.tuling.com转发给后端的tomcat-service-yaml 服务,新建一个文件ingress-tomcat.yaml,内容如下:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - host: tomcat.amam.com  #转发域名
    http:
      paths:
      - path: /                     # 这个path可以写多个
        backend:
          serviceName: tomcat-service-yaml
          servicePort: 80  #service的端口

执行如下命令生效规则:

kubectl apply -f ingress-tomcat.yaml 

查看生效的ingress规则:

kubectl get ing

因为域名没有公网ip 无法直接访问需要配置host 这个host文件在 win10客户机在目录:C:\Windows\System32\drivers\etc

在host文件中添加  
  192.168.123.203  tomcat.tuling.com
	或者
  192.168.123.210  tomcat.tuling.com

192.168.123.203 与 192.168.123.210 是我虚拟机的IP

存储卷使用
通过存储卷,我们可以把外部数据挂载到容器中去,供容器中的应用访问,这样就算容器崩溃了,数据依然可以存在。
之前我们使用Docker部署软件时是可以挂载文件的

docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx  \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
K8S也可以挂载文件,添加配置文件nginx-volume-deployment.yaml用于创建Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-volume-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.10
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: html-volume
            - mountPath: /var/log/nginx
              name: logs-volume
            - mountPath: /etc/nginx
              name: conf-volume
      volumes:
        - name: html-volume
          hostPath:
            path: /home/docker/mydata/nginx/html
            type: Directory
        - name: logs-volume
          hostPath:
            path: /home/docker/mydata/nginx/logs
            type: Directory
        - name: conf-volume
          hostPath:
            path: /home/docker/mydata/nginx/conf
            type: Directory

kubectl 排查服务问题
K8S 上部署服务失败了怎么排查?
用这个命令:

kubectl describe ${RESOURCE} ${NAME}

拉到最后看到Events部分,会显示出 K8S 在部署这个服务过程的关键日志。
一般来说,通过kubectl describe pod ${POD_NAME}已经能定位绝大部分部署失败的问题了,当然,具体问题还是得具体分析。

K8S 上部署的服务不正常怎么排查?
如果服务部署成功了,且状态为running,那么就需要进入 Pod 内部的容器去查看自己的服务日志了:
查看 Pod 内部容器打印的日志:

kubectl logs ${POD_NAME}

进入 Pod 内部某个 container:

kubectl exec -it [options] ${POD_NAME} -c ${CONTAINER_NAME} [args]

K8S真的放弃Docker了吗?

事情是这样的由于docker刚出来的时候跟现在k8s一样很火导致docker的市场大然后docker就耍大牌不给k8s做兼容 目前的兼容都是k8s做的 现在k8s做的火了互联网都在用而docker还是不给做兼容 所以k8s宣布之后可能会弃用docker 如果docker做出妥协 k8s还是会用docker的

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐