K8S是Kubernetes的简称,它是一个开源的容器编排系统,用于自动化应用容器的部署、扩展和管理。
Kubernetes的核心组件:
- Master节点:Master节点包含了控制Kubernetes集群的组件。这些组件包括kube-apiserver、kube-controller-manager和kube-scheduler。
- Worker节点:Worker节点运行应用容器,并包含必要的组件来运行这些容器,包括kubelet和kube-proxy。
- Etcd:Etcd是一个分布式的键值存储系统,用于保存Kubernetes所有的集群数据。
- Kube-apiserver:Kube-apiserver是Kubernetes API的主要实现,它用于暴露Kubernetes API。
- Kube-controller-manager:Kube-controller-manager负责运行Kubernetes控制器,如节点控制器、副本控制器等。
- Kube-scheduler:Kube-scheduler负责在集群中的Worker节点上调度Pods。
- Kubelet:Kubelet负责在每一个Worker节点上启动、停止和维护Pods。
- Kube-proxy:Kube-proxy为Kubernetes Service实现网络代理,这是每个节点上的网络规则,允许网络请求从外部网络到达Pods。
以上这些是Kubernetes的主要组件,每一个都有它自己的特定的职责,并共同工作以保持集群的健康状态。这种架构设计使Kubernetes能够提供高度的可扩展性和可靠性,以满足不同的复杂应用部署需求。
在声明式API中,您定义资源的期望状态并将其提交给Kubernetes API服务器。Kubernetes控制器管理器会持续监视提交的资源定义,并采取行动以使实际状态与期望状态一致。
下面是使用Kubernetes声明式API创建资源的示例:
Pod是Kubernetes的最小可部署单元,它包含一个或多个容器。在Pod中的容器会共享存储和网络。
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.14.2
apiVersion: v1
:指定你正在使用的Kubernetes API的版本来创建这个服务。kind:
Pod:定义正在创建的Kubernetes对象的种类,在这个案例中,是一个Pod。metadata: name:
nginx-pod:元数据字段被用来命名服务对象为"myapp"。spec: selector: app:
myapp:这个字段被用来选择服务将路由流量的Pod。在这种情况下,它选择带有标签 "app=myapp" 的Pod。spec: containers: - name: nginx
:在Pod规范中,定义一个名为 "nginx" 的容器。image: nginx:1.14.2
:指定应该为容器使用版本为1.14.2的nginx镜像。kind: Pod
Deployment是一种抽象资源对象,用于定义和管理应用程序的副本数量和更新策略,以实现应用程序的高可用性和弹性。它提供了一种简单的方式来部署和扩展应用程序,并自动处理副本的创建、更新和回滚等操作。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
apiVersion: apps/v1
:指定用于创建Deployment对象的API版本。kind: Deployment
:定义正在创建的Kubernetes对象的种类,在这种情况下,是Deployment。metadata: name: nginx-deployment
:元数据字段用于将Deployment对象命名为"nginx-deployment"。spec: replicas: 3
:在spec字段下,规定应有3个Pod的副本。selector: matchLabels: app: nginx
:此字段用于选择Deployment管理的Pod。在这种情况下,它正在选择带有标签"app=nginx"的pods。template: metadata: labels: app: nginx
:它正在为创建新的Pods定义一个模板。在这里,任何新创建的Pods将带有"app=nginx"的标签。spec: containers: - name: nginx
:在Pod spec中,它定义了一个名为"nginx"的容器。image: nginx:1.14.2
:指定应该为容器使用nginx版本1.14.2的镜像。ports: - containerPort: 80
:它声明nginx容器应该暴露端口80。
Service是Kubernetes提供的一种抽象,它定义了访问Pod的统一方式,如负载均衡和服务发现。
yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 9376
apiVersion: v1
:指定您正在使用的Kubernetes API的版本来创建此服务。kind: Service
:定义正在创建的Kubernetes对象的类型,在这种情况下,是一个服务。metadata: name: my-service
:元数据字段用于将服务对象命名为"my-service"。spec: selector: app: MyApp
:此字段用于选择服务将路由流量的Pods。在这种情况下,它正在选择带有标签"app=MyApp"的Pods。ports: - protocol: TCP
:此字段指定服务将路由TCP流量。port: 80
:这是可以访问服务的端口。targetPort: 9376
:这是服务将路由流量的Pods上的端口。被这个服务选中的Pods应该在这个端口上监听他们的应用程序。
Ingress是一种API对象,允许外部访问集群内的服务。它充当流量路由器和负载均衡器,根据Ingress资源中定义的规则将传入的流量定向到相应的服务。它提供了一种配置HTTP和HTTPS路由、虚拟主机和SSL/TLS终止的方式。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /echo
pathType: Prefix
backend:
service:
name: echo-server
port:
number: 80
apiVersion: networking.k8s.io/v1
:指定创建Ingress时使用的API版本。kind: Ingress
:定义要创建的Kubernetes对象的类型,即Ingress。metadata: name: my-ingress
:元数据字段用于将Ingress对象命名为"my-ingress"。spec: rules
:该字段指定Ingress的路由规则。host: example.com
:此规则匹配主机头设置为"example.com"的请求。http: paths
:该字段定义要匹配规则的HTTP路径。path: /echo
:该规则匹配路径为"/echo"的请求。pathType: Prefix
:路径匹配类型,设置为"Prefix"以匹配具有给定前缀的路径。backend: service
:该字段指定要将流量路由到的后端服务。name: echo-server
:流量将被定向到的Service的名称。port: number: 80
:应该处理流量的Service的目标端口。
IngressClass是一个资源,定义了Ingress控制器的类别。它允许你指定控制器的实现细节和处理Ingress资源的配置选项。Ingress控制器使用这些信息来确定它们应该处理的Ingress规则。
yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: my-ingress-class
spec:
controller: my-ingress-controller
parameters:
apiGroup: networking.k8s.io/v1
kind: IngressClass
name: my-ingress-class
apiVersion: networking.k8s.io/v1
:指定创建IngressClass时使用的API版本。kind: IngressClass
:定义要创建的Kubernetes对象的类型,即IngressClass。metadata: name: my-ingress-class
:元数据字段用于将IngressClass对象命名为"my-ingress-class"。spec: controller: my-ingress-controller
:指定应处理与此类关联的Ingress对象的Ingress控制器的名称。parameters: apiGroup
、kind
、name
:这些字段定义了特定于Ingress控制器的其他参数。
Ingress Controller是负责处理Ingress资源并管理集群中服务的入站流量的组件。它通常作为一个单独的进程运行,并与底层基础架构交互以配置必要的路由规则。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kong-ingress-controller
namespace: kong
spec:
replicas: 1
selector:
matchLabels:
app: kong-ingress-controller
template:
metadata:
labels:
app: kong-ingress-controller
spec:
containers:
- name: kong-ingress-controller
image: kong/kubernetes-ingress-controller:1.4
env:
- name: KONG_PROXY_LISTEN
value: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
- name: KONG_ADMIN_LISTEN
value: "0.0.0.0:8444 ssl"
- name: KONG_DATABASE
value: "postgres"
- name: KONG_PG_HOST
value: "kong-database.default.svc.cluster.local"
- name: KONG_PG_USER
value: "kong"
- name: KONG_PG_PASSWORD
value: "kong"
- name: KONG_PG_DATABASE
value: "kong"
replicas
:指示要运行的Kong Ingress Controller副本(Pod)数量。selector
:指定用于选择由此部署控制的Pod的标签。metadata
:labels
:用于标识由此部署控制的Pod的标签。spec
:containers
:指定在Pod中运行的容器。name
:指定容器的名称。image
:指定Kong Ingress Controller的容器镜像。env
:指定容器的环境变量。KONG_PROXY_LISTEN
:定义Kong应监听传入请求的IP地址和端口。KONG_ADMIN_LISTEN
:定义Kong管理界面的IP地址和端口。KONG_DATABASE
:指定Kong的后端数据库(例如:"postgres"、"cassandra"等)。KONG_PG_HOST
:指定Kong使用的PostgreSQL数据库的主机名。KONG_PG_USER
:指定连接到PostgreSQL数据库的用户名。KONG_PG_PASSWORD
:指定连接到PostgreSQL数据库的密码。KONG_PG_DATABASE
:指定Kong使用的PostgreSQL数据库的名称。
我们通过一个deployment来部署一个nginx服务器
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80
在此示例中,我们定义了一个名为my-deployment的Deployment资源,有三个副本。Deployment管理一组Pod,每个Pod基于给定的模板创建。模板指定了一个名为my-container的容器,它使用nginx:latest镜像在端口80上运行。
使用kubectl命令应用配置
kubectl apply -f deployment.yaml
kubectl apply命令将deployment.yaml文件提交给Kubernetes API服务器。服务器处理YAML文件并创建所需的Deployment和相关资源。
检查Deployment的状态:
arduino
kubectl get deployment my-deployment
kubectl get命令检索Deployment的当前状态。您应该会看到类似以下的输出:
vbnet
NAME READY UP-TO-DATE AVAILABLE AGE
my-deployment 3/3 3 3 1m
输出表示Deployment有三个副本,所有副本都已准备就绪并可用。
更新Deployment: 修改deployment.yaml文件,将副本数从3更改为5:
ini
kubectl scale deployment my-deployment --replicas=5
使用与之前相同的kubectl apply命令应用更新后的配置:
kubectl apply -f deployment.yaml
Kubernetes控制平面检测到期望状态的更改,并采取必要的操作进行调和将副本数扩展为5。
vbnet
NAME READY UP-TO-DATE AVAILABLE AGE
my-deployment 5/5 5 5 2m

通过使用Kubernetes声明式API,您可以使用配置文件定义和管理Kubernetes资源的期望状态,并将其存储在ETCD中,K8S中控制器用于监控集群中资源状态的变化,通过调协将资源的实际运行状态不断向期望状态靠拢,所以当控制器发现期望副本数变为5时,而集群中应用副本数实际状态为3,就会创建2个pod以达到实际状态与期望状态相匹配。
Reference