使用AWS CloudFormation和OpsWorks构建Kubernetes集群及高级集群管理
1. 使用AWS CloudFormation进行快速资源配置
AWS CloudFormation是一项让AWS资源创建变得轻松的服务。只需一个简单的JSON格式文本文件,就能通过几次点击创建应用程序基础设施。系统管理员和开发人员可以轻松创建、更新和管理AWS资源,无需担心人为错误。
1.1 准备工作
CloudFormation的基本单位是栈(stack),一个栈由一个CloudFormation模板创建,该模板是一个以JSON格式列出AWS资源的文本文件。在AWS控制台使用CloudFormation模板启动栈之前,先了解一下CloudFormation控制台的标签名称:
| 标签名称 | 描述 |
| ---- | ---- |
| Overview | 栈配置文件概述,列出名称、状态和描述 |
| Output | 此栈的输出字段 |
| Resources | 此栈中列出的资源 |
| Events | 在此栈中进行操作时的事件 |
| Template | JSON格式的文本文件 |
| Parameters | 此栈的输入参数 |
| Tags | 资源的AWS标签 |
| Stack Policy | 更新期间使用的栈策略,可防止意外删除或更新资源 |
一个CloudFormation模板包含多个部分,示例模板如下:
{
"AWSTemplateFormatVersion":"AWS CloudFormation templateversion date",
"Description":"stack description",
"Metadata":{
# put additional information for this template
},
"Parameters":{
# user-specified the input of your template
},
"Mappings":{
# using for define conditional parameter values and use it in the template
},
"Conditions":{
# use to define whether certain resources are created, configured in a certain condition.
},
"Resources":{
# major section in the template, use to create and configure AWS resources
},
"Outputs":{
# user-specified output
}
}
我们主要使用以下三个部分:
- Parameters:创建栈时可能需要输入的变量。
- Resources:声明AWS资源设置的主要部分。
- Outputs:可能希望暴露给CloudFormation UI的部分,以便在部署模板时轻松找到资源的输出信息。
AWS CloudFormation提供了一些内置的固有函数,用于链接资源。常见的函数如下:
| 函数 | 描述 | 用法 |
| ---- | ---- | ---- |
| Fn::GetAtt | 从资源中检索属性的值 |
{"Fn::GetAtt" : [ "logicalNameOfResource", "attributeName" ]}
|
| Fn::GetAZs | 返回指定区域的可用区列表 |
{"Fn::GetAZs" : "us-east-1"}
|
| Fn::Select | 从列表中选择一个值 |
{ "Fn::Select" : [ index, listOfObjects ]}
|
| Ref | 从逻辑名称或参数返回一个值 |
{"Ref" : "logicalName"}
|
1.2 创建网络基础设施
我们将创建一个带有10.0.0.0/16的VPC,其中包含两个公共子网和两个私有子网。此外,还会创建一个互联网网关,并向公共子网添加相关路由表规则,以将流量路由到外部网络。同时,创建一个位于公共子网且带有弹性IP的NAT网关,确保私有子网可以访问互联网。
操作步骤如下:
1.
定义参数
:在模板开头定义两个参数
Prefix
和
CIDRPrefix
。
"Parameters":{
"Prefix":{
"Description":"Prefix of resources",
"Type":"String",
"Default":"KubernetesSample",
"MinLength":"1",
"MaxLength":"24",
"ConstraintDescription":"Length is too long"
},
"CIDRPrefix":{
"Description":"Network cidr prefix",
"Type":"String",
"Default":"10.0",
"MinLength":"1",
"MaxLength":"8",
"ConstraintDescription":"Length is too long"
}
}
-
创建VPC
:创建一个逻辑名称为
VPC、类型为AWS::EC2::VPC的资源。
"VPC":{
"Type":"AWS::EC2::VPC",
"Properties":{
"CidrBlock":{
"Fn::Join":[
".",
[
{
"Ref":"CIDRPrefix"
},
"0.0/16"
]
]
},
"EnableDnsHostnames":"true",
"Tags":[
{
"Key":"Name",
"Value":{
"Fn::Join":[
".",
[
{
"Ref":"Prefix"
},
"vpc"
]
]
}
},
{
"Key":"EnvName",
"Value":{
"Ref":"Prefix"
}
}
]
}
}
-
创建公共子网
:创建第一个公共子网,使用
Fn::Select选择可用区。
"SubnetPublicA":{
"Type":"AWS::EC2::Subnet",
"Properties":{
"VpcId":{
"Ref":"VPC"
},
"CidrBlock":{
"Fn::Join":[
".",
[
{
"Ref":"CIDRPrefix"
},
"0.0/24"
]
]
},
"AvailabilityZone":{
"Fn::Select":[
"0",
{
"Fn::GetAZs":""
}
]
},
"Tags":[
{
"Key":"Name",
"Value":{
"Fn::Join":[
".",
[
{
"Ref":"Prefix"
},
"public",
"subnet",
"A"
]
]
}
},
{
"Key":"EnvName",
"Value":{
"Ref":"Prefix"
}
}
]
}
}
- 创建互联网网关和VPC网关附件 :创建互联网网关并将其附加到VPC。
"InternetGateway":{
"Type":"AWS::EC2::InternetGateway",
"Properties":{
"Tags":[
{
"Key":"Stack",
"Value":{
"Ref":"AWS::StackId"
}
},
{
"Key":"Name",
"Value":{
"Fn::Join":[
".",
[
{
"Ref":"Prefix"
},
"vpc",
"igw"
]
]
}
},
{
"Key":"EnvName",
"Value":{
"Ref":"Prefix"
}
}
]
}
},
"GatewayAttachment":{
"Type":"AWS::EC2::VPCGatewayAttachment",
"Properties":{
"VpcId":{
"Ref":"VPC"
},
"InternetGatewayId":{
"Ref":"InternetGateway"
}
}
}
-
创建NAT网关
:先创建EIP,再创建NAT网关,并使用
DependsOn确保顺序。
"NatGatewayEIP":{
"Type":"AWS::EC2::EIP",
"DependsOn":"GatewayAttachment",
"Properties":{
"Domain":"vpc"
}
},
"NatGateway":{
"Type":"AWS::EC2::NatGateway",
"DependsOn":"NatGatewayEIP",
"Properties":{
"AllocationId":{
"Fn::GetAtt":[
"NatGatewayEIP",
"AllocationId"
]
},
"SubnetId":{
"Ref":"SubnetPublicA"
}
}
}
- 创建路由表和路由 :分别为公共子网和私有子网创建路由表和路由。
"RouteTableInternet":{
"Type":"AWS::EC2::RouteTable",
"Properties":{
"VpcId":{
"Ref":"VPC"
},
"Tags":[
{
"Key":"Stack",
"Value":{
"Ref":"AWS::StackId"
}
},
{
"Key":"Name",
"Value":{
"Fn::Join":[
".",
[
{
"Ref":"Prefix"
},
"internet",
"routetable"
]
]
}
},
{
"Key":"EnvName",
"Value":{
"Ref":"Prefix"
}
}
]
}
},
"RouteInternet":{
"Type":"AWS::EC2::Route",
"DependsOn":"GatewayAttachment",
"Properties":{
"RouteTableId":{
"Ref":"RouteTableInternet"
},
"DestinationCidrBlock":"0.0.0.0/0",
"GatewayId":{
"Ref":"InternetGateway"
}
}
},
"RouteNat":{
"Type":"AWS::EC2::Route",
"DependsOn":"RouteTableNat",
"Properties":{
"RouteTableId":{
"Ref":"RouteTableNat"
},
"DestinationCidrBlock":"0.0.0.0/0",
"NatGatewayId":{
"Ref":"NatGateway"
}
}
}
-
关联子网和路由表
:使用
SubnetRouteTableAssociation关联子网和路由表。
"SubnetRouteTableInternetAssociationA":{
"Type":"AWS::EC2::SubnetRouteTableAssociation",
"Properties":{
"SubnetId":{
"Ref":"SubnetPublicA"
},
"RouteTableId":{
"Ref":"RouteTableInternet"
}
}
},
"SubnetRouteTableNatAssociationA":{
"Type":"AWS::EC2::SubnetRouteTableAssociation",
"Properties":{
"SubnetId":{
"Ref":"SubnetPrivateA"
},
"RouteTableId":{
"Ref":"RouteTableNat"
}
}
}
完成网络基础设施模板后,在AWS控制台启动栈:
1. 点击并启动栈,选择VPC示例模板。
2. 点击下一步,会看到参数页面,可使用默认值,也可在创建/更新栈时更改。
3. 点击完成,CloudFormation将开始创建模板中声明的资源,完成后状态将显示为
CREATE_COMPLETE
。
1.3 创建用于应用程序管理的OpsWorks
对于应用程序管理,我们将利用AWS的OpsWorks,它是一种应用程序生命周期管理工具。
操作步骤如下:
1.
定义参数
:定义八个参数,包括Kubernetes主节点和etcd的基本认证信息,以及VPC ID和私有子网ID。
"Parameters":{
"Prefix":{
"Description":"Prefix of resources",
"Type":"String",
"Default":"KubernetesSample",
"MinLength":"1",
"MaxLength":"24",
"ConstraintDescription":"Length is too long"
},
"PrivateNetworkCIDR":{
"Default":"192.168.0.0/16",
"Description":"Desired Private Network CIDR or Flanneld (must not overrap VPC CIDR)",
"Type":"String",
"MinLength":"9",
"AllowedPattern":"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/\\d{1,2}",
"ConstraintDescription":"PrivateNetworkCIDR must be IPv4 format"
},
"VPCId":{
"Description":"VPC Id",
"Type":"AWS::EC2::VPC::Id"
},
"SubnetPrivateIdA":{
"Description":"Private SubnetA",
"Type":"AWS::EC2::Subnet::Id"
},
"SubnetPrivateIdB":{
"Description":"Private SubnetB",
"Default":"subnet-9007ecc9",
"Type":"AWS::EC2::Subnet::Id"
},
"K8sMasterBaAccount":{
"Default":"admin",
"Description":"The account of basic authentication for k8s Master",
"Type":"String",
"MinLength":"1",
"MaxLength":"75",
"AllowedPattern":"[a-zA-Z0-9]*",
"ConstraintDescription":"Account and Password should follow Base64 pattern"
},
"K8sMasterBaPassword":{
"Default":"Passw0rd",
"Description":"The password of basic authentication for k8s Master",
"Type":"String",
"MinLength":"1",
"MaxLength":"75",
"NoEcho":"true",
"AllowedPattern":"[a-zA-Z0-9]*",
"ConstraintDescription":"Account and Password should follow Base64 pattern"
},
"EtcdBaPassword":{
"Default":"Passw0rd",
"Description":"The password of basic authentication for Etcd",
"Type":"String",
"MinLength":"1",
"MaxLength":"71",
"NoEcho":"true",
"AllowedPattern":"[a-zA-Z0-9]*",
"ConstraintDescription":"Password should follow Base64 pattern"
}
}
- 创建IAM角色 :在开始创建OpsWorks栈之前,需要为其创建两个IAM角色,一个是服务角色,用于启动实例、附加ELB等;另一个是实例角色,用于定义OpsWorks实例访问AWS资源的权限。
- 定义安全组 :以Kubernetes主节点为例,定义安全组以允许特定流量。
"SecurityGroupELBKubMaster":{
"Type":"AWS::EC2::SecurityGroup",
"Properties":{
"GroupDescription":{
"Ref":"Prefix"
},
"SecurityGroupIngress":[
{
"IpProtocol":"tcp",
"FromPort":"80",
"ToPort":"80",
"CidrIp":"0.0.0.0/0"
},
{
"IpProtocol":"tcp",
"FromPort":"8080",
"ToPort":"8080",
"SourceSecurityGroupId":{
"Ref":"SecurityGroupKubNode"
}
}
],
"VpcId":{
"Ref":"VPCId"
},
"Tags":[
{
"Key":"Application",
"Value":{
"Ref":"AWS::StackId"
}
},
{
"Key":"Name",
"Value":{
"Fn::Join":[
"-",
[
{
"Ref":"Prefix"
},
"SGElbKubMaster"
]
]
}
}
]
}
},
"SecurityGroupKubMaster":{
"Type":"AWS::EC2::SecurityGroup",
"Properties":{
"GroupDescription":{
"Ref":"Prefix"
},
"SecurityGroupIngress":[
{
"IpProtocol":"tcp",
"FromPort":"22",
"ToPort":"22",
"CidrIp":"0.0.0.0/0"
},
{
"IpProtocol":"tcp",
"FromPort":"8080",
"ToPort":"8080",
"SourceSecurityGroupId":{
"Ref":"SecurityGroupELBKubMaster"
}
},
{
"IpProtocol":"tcp",
"FromPort":"6443",
"ToPort":"6443",
"SourceSecurityGroupId":{
"Ref":"SecurityGroupELBKubMaster"
}
}
],
"VpcId":{
"Ref":"VPCId"
},
"Tags":[
{
"Key":"Application",
"Value":{
"Ref":"AWS::StackId"
}
},
{
"Key":"Name",
"Value":{
"Fn::Join":[
"-",
[
{
"Ref":"Prefix"
},
"SG-KubMaster"
]
]
}
}
]
}
}
- 创建OpsWorks栈 :使用CustomJson作为Chef配方的输入。
"OpsWorksStack":{
"Type":"AWS::OpsWorks::Stack",
"Properties":{
"DefaultInstanceProfileArn":{
"Fn::GetAtt":[
"RootInstanceProfile",
"Arn"
]
},
"CustomJson":{
"kubernetes":{
"cluster_cidr":{
"Ref":"PrivateNetworkCIDR"
},
"version":"1.1.3",
"master_url":{
"Fn::GetAtt":[
"ELBKubMaster",
"DNSName"
]
}
},
"ba":{
"account":{
"Ref":"K8sMasterBaAccount"
},
"password":{
"Ref":"K8sMasterBaPassword"
},
"uid":1234
},
"etcd":{
"password":{
"Ref":"EtcdBaPassword"
},
"elb_url":{
"Fn::GetAtt":[
"ELBEtcd",
"DNSName"
]
}
},
"opsworks_berkshelf":{
"debug":true
}
},
"ConfigurationManager":{
"Name":"Chef",
"Version":"11.10"
},
"UseCustomCookbooks":"true",
"UseOpsworksSecurityGroups":"false",
"CustomCookbooksSource":{
"Type":"git",
"Url":"https://github.com/kubernetes-cookbook/opsworks-recipes.git"
},
"ChefConfiguration":{
"ManageBerkshelf":"true"
},
"DefaultOs":"Red Hat Enterprise Linux 7",
"DefaultSubnetId":{
"Ref":"SubnetPrivateIdA"
},
"Name":{
"Ref":"Prefix"
},
"ServiceRoleArn":{
"Fn::GetAtt":[
"OpsWorksServiceRole",
"Arn"
]
},
"VpcId":{
"Ref":"VPCId"
}
}
}
- 创建层 :以Kubernetes主节点为例,创建层并定义Chef的运行列表。
"OpsWorksLayerKubMaster":{
"Type":"AWS::OpsWorks::Layer",
"Properties":{
"Name":"Kubernetes Master",
"Shortname":"kube-master",
"AutoAssignElasticIps":"false",
"AutoAssignPublicIps":"false",
"CustomSecurityGroupIds":[
{
"Ref":"SecurityGroupKubMaster"
}
],
"EnableAutoHealing":"false",
"StackId":{
"Ref":"OpsWorksStack"
},
"Type":"custom",
"CustomRecipes":{
"Setup":[
"kubernetes-rhel::flanneld",
"kubernetes-rhel::repo-setup",
"kubernetes-rhel::master-setup"
],
"Deploy":[
"kubernetes-rhel::master-run"
]
}
}
}
- 创建ELB并附加到栈 :创建Kubernetes主节点的ELB,并将其附加到层。
"ELBKubMaster":{
"DependsOn":"SecurityGroupELBKubMaster",
"Type":"AWS::ElasticLoadBalancing::LoadBalancer",
"Properties":{
"LoadBalancerName":{
"Fn::Join":[
"-",
[
{
"Ref":"Prefix"
},
"Kub"
]
]
},
"Scheme":"internal",
"Listeners":[
{
"LoadBalancerPort":"80",
"InstancePort":"6443",
"Protocol":"HTTP",
"InstanceProtocol":"HTTPS"
},
{
"LoadBalancerPort":"8080",
"InstancePort":"8080",
"Protocol":"HTTP",
"InstanceProtocol":"HTTP"
}
],
"HealthCheck":{
"Target":"HTTP:8080/version",
"HealthyThreshold":"2",
"UnhealthyThreshold":"10",
"Interval":"10",
"Timeout":"5"
},
"Subnets":[
{
"Ref":"SubnetPrivateIdA"
},
{
"Ref":"SubnetPrivateIdB"
}
],
"SecurityGroups":[
{
"Fn::GetAtt":[
"SecurityGroupELBKubMaster",
"GroupId"
]
}
]
}
},
"OpsWorksELBAttachKubMaster":{
"Type":"AWS::OpsWorks::ElasticLoadBalancerAttachment",
"Properties":{
"ElasticLoadBalancerName":{
"Ref":"ELBKubMaster"
},
"LayerId":{
"Ref":"OpsWorksLayerKubMaster"
}
}
}
etcd的ELB设置类似,但健康检查监听
HTTP:4001/version
,并将外部的80流量重定向到实例的4001端口。启动第二个示例模板后,应该能看到OpsWorks栈、层、安全组、IAM和ELB。如果想使用CloudFormation默认启动,只需添加
AWS::OpsWorks::Instance
资源类型并指定规格即可。
2. Kubernetes高级集群管理
2.1 kubeconfig高级设置
kubeconfig是用于管理Kubernetes集群、上下文和认证设置的配置文件。通过它,我们可以设置不同的集群凭证、用户和命名空间,以便在不同集群或集群内的不同上下文之间切换。可以使用
kubectl config
子命令通过命令行配置,也可以直接使用配置文件。
操作步骤如下:
1.
检查当前kubeconfig设置
:使用
kubectl config view
查看当前设置。
# kubectl config view
apiVersion: v1
clusters: []
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []
-
运行nginx实例
:假设我们有两个集群,一个在本地
http://localhost:8080,另一个在远程http://remotehost:8080。在两个集群中分别运行不同数量的nginx实例。
# 在本地集群
# kubectl run localnginx --image=nginx --replicas=2 --port=80
replicationcontroller "localnginx" created
# kubectl get pods
NAME READY STATUS RESTARTS AGE
localnginx-1blru 1/1 Running 0 1m
localnginx-p6cyo 1/1 Running 0 1m
# 在远程集群
# kubectl run remotenginx --image=nginx --replicas=4 --port=80
replicationcontroller "remotenginx" created
# kubectl get pods
NAME READY STATUS RESTARTS AGE
remotenginx-6wz5c 1/1 Running 0 1m
remotenginx-7v5in 1/1 Running 0 1m
remotenginx-c7go6 1/1 Running 0 1m
remotenginx-r1mf6 1/1 Running 0 1m
-
设置新的凭证
:为每个集群设置两个凭证,使用
kubectl config set-credentials命令。
# 在本地集群,添加用户`userlocal`,昵称`localhost/myself`
# kubectl config set-credentials localhost/myself --username=userlocal --password=passwordlocal
user "localhost/myself" set.
# 在本地集群,添加用户`userremote`,昵称`remotehost/myself`
# kubectl config set-credentials remotehost/myself --username=userremote --password=passwordremote
user "remotehost/myself" set.
# 查看当前设置
# kubectl config view
apiVersion: v1
clusters: []
contexts: []
current-context: ""
kind: Config
preferences: {}
users:
- name: localhost/myself
user:
password: passwordlocal
username: userlocal
- name: remotehost/myself
user:
password: passwordremote
username: userremote
-
设置新的集群
:使用
kubectl config set-cluster命令设置新集群。
# 在本地集群,添加`http://localhost:8080`作为`localhost`
# kubectl config set-cluster localhost --insecure-skip-tls-verify=true --server=http://localhost:8080
cluster "localhost" set.
# 在本地集群,添加`http://remotehost:8080`作为`remotehost`
# kubectl config set-cluster remotehost --insecure-skip-tls-verify=true --server=http://remotehost:8080
cluster "remotehost" set.
# 查看当前设置
# kubectl config view
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: http://localhost:8080
name: localhost
- cluster:
insecure-skip-tls-verify: true
server: http://remotehost:8080
name: remotehost
contexts: []
current-context: ""
kind: Config
preferences: {}
users:
- name: localhost/myself
user:
password: passwordlocal
username: userlocal
- name: remotehost/myself
user:
password: passwordremote
username: userremote
-
设置和更改当前上下文
:使用
kubectl config set-context命令设置上下文,使用kubectl config use-context命令切换上下文。
# 在本地集群,为本地集群设置名为`default/localhost/myself`的上下文
# kubectl config set-context default/localhost/myself --user=localhost/myself --namespace=default --cluster=localhost
context "default/localhost/myself" set.
# 在本地集群,为远程集群设置名为`default/remotehost/myself`的上下文
# kubectl config set-context default/remotehost/myself --user=remotehost/myself --namespace=default --cluster=remotehost
context "default/remotehost/myself" set.
# 查看当前设置
# kubectl config view
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: http://localhost:8080
name: localhost
- cluster:
insecure-skip-tls-verify: true
server: http://remotehost:8080
name: remotehost
contexts:
- context:
cluster: localhost
namespace: default
user: localhost/myself
name: default/localhost/myself
- context:
cluster: remotehost
namespace: default
user: remotehost/myself
name: default/remotehost/myself
current-context: ""
kind: Config
preferences: {}
users:
- name: localhost/myself
user:
password: passwordlocal
username: userlocal
- name: remotehost/myself
user:
password: passwordremote
username: userremote
# 在本地集群,使用`default/localhost/myself`上下文
# kubectl config use-context default/localhost/myself
switched to context "default/localhost/myself".
# kubectl get pods
NAME READY STATUS RESTARTS AGE
localnginx-1blru 1/1 Running 0 1m
localnginx-p6cyo 1/1 Running 0 1m
# 在本地集群,切换到`default/remotehost/myself`上下文
# kubectl config use-context default/remotehost/myself
switched to context "default/remotehost/myself".
# kubectl get pods
NAME READY STATUS RESTARTS AGE
remotenginx-6wz5c 1/1 Running 0 1m
remotenginx-7v5in 1/1 Running 0 1m
remotenginx-c7go6 1/1 Running 0 1m
remotenginx-r1mf6 1/1 Running 0 1m
通过kubeconfig,我们可以轻松地在多个集群和多个用户之间进行切换。
2.2 设置节点资源
Kubernetes 允许用户为节点设置资源,确保每个节点上的 Pod 不会过度消耗资源,从而保证集群的稳定性和性能。
操作步骤如下:
1.
查看节点资源
:使用
kubectl describe node <node-name>
命令查看节点的资源信息,包括 CPU、内存、存储等。
# kubectl describe node my-node
Name: my-node
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=my-node
kubernetes.io/os=linux
Annotations: node.alpha.kubernetes.io/ttl=0
volumes.kubernetes.io/controller-managed-attach-detach=true
CreationTimestamp: Tue, 01 Jun 2023 12:00:00 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: my-node
AcquireTime: <unset>
RenewTime: Tue, 01 Jun 2023 12:30:00 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Tue, 01 Jun 2023 12:30:00 +0000 Tue, 01 Jun 2023 12:00:00 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Tue, 01 Jun 2023 12:30:00 +0000 Tue, 01 Jun 2023 12:00:00 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Tue, 01 Jun 2023 12:30:00 +0000 Tue, 01 Jun 2023 12:00:00 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Tue, 01 Jun 2023 12:30:00 +0000 Tue, 01 Jun 2023 12:00:00 +0000 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 192.168.1.100
Hostname: my-node
Capacity:
cpu: 4
ephemeral-storage: 100Gi
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 8192Mi
pods: 110
Allocatable:
cpu: 4
ephemeral-storage: 92Gi
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 7892Mi
pods: 110
System Info:
Machine ID: 1234567890abcdef1234567890abcdef
System UUID: ABCDEFGH-1234-5678-90AB-CDEFGHIJKL
Boot ID: 12345678-1234-5678-90AB-CDEFGHIJKL
Kernel Version: 5.4.0-100-generic
OS Image: Ubuntu 20.04.2 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://20.10.7
Kubelet Version: v1.21.0
Kube-Proxy Version: v1.21.0
Non-terminated Pods: (3 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
default my-pod-1 100m 200m 256Mi 512Mi 1h
default my-pod-2 200m 300m 512Mi 1024Mi 1h
kube-system coredns-74ff55c5b-98g7h 100m 100m 70Mi 170Mi 1h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 400m 600m
memory 838Mi 1706Mi
ephemeral-storage 0 0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal NodeHasSufficientMemory 1h kubelet Node my-node status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 1h kubelet Node my-node status is now: NodeHasNoDiskPressure
Normal NodeHasSufficientPID 1h kubelet Node my-node status is now: NodeHasSufficientPID
- 设置资源请求和限制 :在 Pod 的 YAML 文件中设置资源请求和限制。
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:1.19.10
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "200m"
memory: "512Mi"
-
部署 Pod
:使用
kubectl apply -f <pod-yaml-file>命令部署 Pod。
# kubectl apply -f my-pod.yaml
pod/my-pod created
-
验证资源设置
:再次使用
kubectl describe node <node-name>命令查看节点的资源使用情况,确保 Pod 的资源请求和限制已生效。
2.3 使用 WebUI
Kubernetes 提供了一个友好的用户界面(WebUI),用于可视化集群的资源状态,如复制控制器、节点和 Pod 等。
操作步骤如下:
1.
启动 WebUI
:使用
kubectl proxy
命令启动代理服务器。
# kubectl proxy
Starting to serve on 127.0.0.1:8001
-
访问 WebUI
:在浏览器中访问
http://127.0.0.1:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/打开 WebUI。 - 查看资源状态 :在 WebUI 中,可以查看集群的各种资源状态,如节点、Pod、复制控制器等。可以通过搜索框查找特定的资源,也可以使用过滤器筛选资源。
2.4 使用 RESTful API
Kubernetes 暴露了 RESTful API,方便与其他系统集成。
操作步骤如下:
1.
获取 API 地址
:使用
kubectl cluster-info
命令获取 API 服务器的地址。
# kubectl cluster-info
Kubernetes control plane is running at https://192.168.1.100:6443
CoreDNS is running at https://192.168.1.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
-
获取认证信息
:使用
kubectl config view --minify --flatten命令获取认证信息,如证书、令牌等。
# kubectl config view --minify --flatten
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR...
server: https://192.168.1.100:6443
name: my-cluster
contexts:
- context:
cluster: my-cluster
user: my-user
name: my-context
current-context: my-context
kind: Config
preferences: {}
users:
- name: my-user
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR...
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlF...
-
发送 RESTful 请求
:使用
curl或其他 HTTP 客户端工具发送 RESTful 请求。例如,获取所有 Pod 的列表:
# curl -k -H "Authorization: Bearer <token>" https://192.168.1.100:6443/api/v1/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/pods",
"resourceVersion": "123456"
},
"items": [
{
"metadata": {
"name": "my-pod-1",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/my-pod-1",
"uid": "12345678-1234-5678-90ab-cdef12345678",
"resourceVersion": "123456",
"creationTimestamp": "2023-06-01T12:00:00Z",
"labels": {
"app": "my-app"
}
},
"spec": {
"containers": [
{
"name": "my-container",
"image": "nginx:1.19.10",
"ports": [
{
"containerPort": 80,
"protocol": "TCP"
}
]
}
]
},
"status": {
"phase": "Running",
"conditions": [
{
"type": "Initialized",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2023-06-01T12:00:00Z"
},
{
"type": "Ready",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2023-06-01T12:05:00Z"
},
{
"type": "ContainersReady",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2023-06-01T12:05:00Z"
},
{
"type": "PodScheduled",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2023-06-01T12:00:00Z"
}
],
"hostIP": "192.168.1.100",
"podIP": "192.168.1.101",
"startTime": "2023-06-01T12:00:00Z"
}
}
]
}
2.5 认证和授权
为了构建安全的集群,需要设置 Kubernetes 的认证和授权。
操作步骤如下:
1.
认证设置
:Kubernetes 支持多种认证方式,如 HTTP 基本认证、客户端证书认证、令牌认证等。以 HTTP 基本认证为例,在 kubeconfig 文件中设置用户名和密码:
# kubectl config set-credentials my-user --username=admin --password=password
user "my-user" set.
- 授权设置 :Kubernetes 使用基于角色的访问控制(RBAC)进行授权。可以创建角色(Role)和角色绑定(RoleBinding)来定义用户或用户组的权限。
# 创建角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
# 创建角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: my-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
-
应用配置
:使用
kubectl apply -f <yaml-file>命令应用角色和角色绑定的配置。
# kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/pod-reader created
# kubectl apply -f role-binding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
通过以上步骤,我们可以实现 Kubernetes 集群的高级管理,包括 kubeconfig 设置、节点资源管理、WebUI 使用、RESTful API 集成以及认证和授权设置。这些功能可以帮助我们更好地管理和维护 Kubernetes 集群,提高集群的安全性和性能。
超级会员免费看
2

被折叠的 条评论
为什么被折叠?



