Kubernetes(K8S)二
K8S核心概念k8s有很多核心概念 先写几个DeploymentDeployment负责创建和更新应用程序的实例 创建Deployment后k8s master将应用程序实例调度到集群中的各个节点上,如果托管实例的节点关闭或被删除,Deployment控制器会将该实例替换为集群中另一个节点上的实例。这提供了一种自我修复机制来解决机器故障维护问题白话就是之前用docker能在单机下载应用程序 运行应
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的
更多推荐
所有评论(0)