EKS Cluster 创建测验 - 第 2 部分
本测验测试你对 Amazon EKS cluster 创建相关的高级概念、安全设置和网络配置的理解。内容涵盖 cluster 安全、network policies 和 service accounts 等主题。
基础概念问题
- 在 Amazon EKS cluster 中,IRSA (IAM Roles for Service Accounts) 的主要用途是什么?
- A) 向 cluster 管理员授予 IAM 权限
- B) 将 IAM roles 分配给 worker nodes
- C) 向 Kubernetes service accounts 授予 AWS service 访问权限
- D) 向 EKS control plane 授予 IAM 权限
显示答案
答案:C) 向 Kubernetes service accounts 授予 AWS service 访问权限
解释: IRSA (IAM Roles for Service Accounts) 的主要用途是向 Kubernetes service accounts 授予 AWS service 访问权限。此功能允许你在 pod 级别提供细粒度权限,并且不用共享 node 级别的 IAM roles,而是只向每个应用授予所需的最低权限。
IRSA 的工作方式:
OpenID Connect (OIDC) Provider 设置:
- EKS cluster 被配置为 OIDC provider。
- 这使 Kubernetes service account tokens 能够成为 AWS IAM 中受信任的身份验证机制。
bash# Associate OIDC provider eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve创建 IAM Role 并配置 Trust Policy:
- 创建 Kubernetes service account 可以 assume 的 IAM role。
- trust policy 限制只有特定 namespaces 中的特定 service accounts 可以 assume 该 role。
json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.region.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.region.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:my-service-account" } } } ] }创建 Service Account 并关联 IAM Role:
- 将 IAM role ARN 作为 annotation 添加到 service account。
yamlapiVersion: v1 kind: ServiceAccount metadata: name: my-service-account namespace: default annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-role在 Pod 中使用 Service Account:
- 在 pod manifest 中指定 service account。
yamlapiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: my-service-account containers: - name: my-container image: my-image
IRSA 的优势:
- 最小权限原则:
- 你可以只向每个应用授予所需的最低权限。
- 按 pod 设置不同权限,而不是共享 node 级别的 IAM roles
- 增强安全性:
- 无需在代码或环境变量中存储 AWS credentials。
- 降低 credentials 泄露风险
- 权限隔离:
- 运行在同一 node 上的不同 pods 可以拥有不同的 IAM 权限。
- 在多租户环境中很重要
- 简化 Credential 管理:
- 无需直接管理 AWS credentials。
- Credential rotation 会自动处理。
使用 eksctl 设置 IRSA 的示例:
# Create service account and IAM role
eksctl create iamserviceaccount \
--name my-service-account \
--namespace default \
--cluster my-cluster \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve
# Verify created service account
kubectl get serviceaccount my-service-account -o yaml其他选项的问题:
- 向 cluster 管理员授予 IAM 权限: 这不是 IRSA 的用途。Cluster 管理员权限通常通过 aws-auth ConfigMap 管理。
- 将 IAM roles 分配给 worker nodes: 这是通过 node IAM roles 完成的,与 IRSA 分开。Node IAM roles 会被所有 pods 共享,这可能违反最小权限原则。
- 向 EKS control plane 授予 IAM 权限: EKS control plane 权限通过 cluster IAM role 管理,与 IRSA 无关。
IRSA 是一项重要功能,它允许 Kubernetes workloads 安全地访问 AWS services,也是在 EKS clusters 上运行应用时推荐的方法。
2. Amazon EKS cluster 中 security groups 的主要作用是什么? - A) 控制 pods 之间的 network traffic - B) 控制 cluster API server 与 nodes 之间的 traffic - C) 应用 Kubernetes RBAC policies - D) 管理用户身份验证
显示答案
答案:B) 控制 cluster API server 与 nodes 之间的 traffic
解释: Amazon EKS cluster 中 security groups 的主要作用是控制 cluster API server 与 nodes 之间的 traffic。Security groups 是 AWS 虚拟防火墙,用于在 EC2 instance 级别控制入站和出站 traffic。在 EKS 中,有 cluster security groups 和 node security groups,它们保护 cluster components 之间的通信。
EKS Clusters 中 Security Groups 的类型:
- Cluster Security Group:
- 应用于 EKS control plane。
- 允许 worker nodes 与 control plane 之间通信。
- 创建 EKS cluster 时默认自动创建。
- 关键规则:
- 允许来自 node security group 的 443 端口入站 traffic
- 允许出站 traffic 到 node security group
- Node Security Group:
- 应用于 worker nodes。
- 允许 nodes 之间以及 nodes 与 control plane 之间通信。
- 关键规则:
- 允许 nodes 之间的所有 traffic
- 允许 443 端口出站 traffic 到 cluster security group
- 允许来自 cluster security group 的入站 traffic
- 为 kubelet 允许 10250 端口
Security Group 配置示例:
Cluster Security Group Rules:
Inbound:
- Protocol: TCP
- Port Range: 443
- Source: Node Security Group
Outbound:
- Protocol: All Traffic
- Port Range: All Ports
- Destination: 0.0.0.0/0Node Security Group Rules:
Inbound:
- Protocol: All Traffic
- Source: Node Security Group itself (node-to-node communication)
- Protocol: TCP
- Port Range: 10250
- Source: Cluster Security Group (kubelet communication)
Outbound:
- Protocol: All Traffic
- Port Range: All Ports
- Destination: 0.0.0.0/0自定义 Security Groups:
创建 EKS cluster 时可以指定自定义 security groups:
# Specifying custom security groups using AWS CLI
aws eks create-cluster \
--name my-cluster \
--role-arn arn:aws:iam::123456789012:role/EksClusterRole \
--resources-vpc-config subnetIds=subnet-12345,subnet-67890,securityGroupIds=sg-12345
# Specifying custom security groups using eksctl
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: my-cluster
region: us-west-2
vpc:
id: vpc-12345
securityGroup: sg-12345
subnets:
private:
us-west-2a: subnet-12345
us-west-2b: subnet-67890Pods 的 Security Groups:
最近,EKS 还支持 pod 级别的 security groups(SecurityGroupsForPods 功能)。这允许你将 security groups 应用于单个 pods:
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
name: my-security-group-policy
namespace: default
spec:
podSelector:
matchLabels:
app: my-app
securityGroups:
groupIds:
- sg-12345其他选项的问题:
- 控制 pods 之间的 network traffic: 默认情况下,pods 之间的 network traffic 通过 Kubernetes Network Policies (NetworkPolicy) 控制,而不是 AWS security groups。虽然 SecurityGroupsForPods 功能允许在 pod 级别应用 security groups,但这不是 security groups 的主要作用。
- 应用 Kubernetes RBAC policies: RBAC (Role-Based Access Control) 是控制 Kubernetes API resources 访问的机制,与 AWS security groups 分开。
- 管理用户身份验证: EKS clusters 中的用户身份验证通过 AWS IAM 与 Kubernetes RBAC 的集成管理,与 security groups 无关。
Security groups 在 EKS clusters 的网络安全中发挥重要作用,保护 cluster components 之间的通信并阻止不必要的 traffic。正确的 security group 配置对于强化 EKS clusters 的安全态势至关重要。
- 在 Amazon EKS cluster 中实现 Kubernetes Network Policies 需要什么?
- A) AWS security group 配置
- B) 支持 network policies 的 CNI plugin,例如 Calico 或 Cilium
- C) AWS Network Firewall 设置
- D) 启用 VPC Flow Logs
显示答案
答案:B) 支持 network policies 的 CNI plugin,例如 Calico 或 Cilium
解释: 要在 Amazon EKS cluster 中实现 Kubernetes Network Policies,你需要一个支持 network policies 的 CNI (Container Network Interface) plugin,例如 Calico 或 Cilium。默认的 Amazon VPC CNI plugin 不支持 network policies,因此必须安装额外组件。
支持 Network Policy 的 CNI 选项:
- Calico:
广泛使用的开源 networking 和 network security 解决方案
可在 EKS 中与 Amazon VPC CNI 一起使用
安装方法:
bash# Install Calico using Helm helm repo add projectcalico https://docs.projectcalico.org/charts helm install calico projectcalico/tigera-operator --namespace tigera-operator --create-namespace # Or install using manifest files kubectl apply -f https://docs.projectcalico.org/manifests/calico-vxlan.yaml
- Cilium:
基于 eBPF 的 networking、安全和可观测性解决方案
提供高性能和高级功能
安装方法:
bash# Install Cilium using Helm helm repo add cilium https://helm.cilium.io/ helm install cilium cilium/cilium --namespace kube-system
- AWS CNI with Cilium:
同时使用 Amazon VPC CNI 和 Cilium 的混合方法
VPC CNI 处理 pod networking,Cilium 处理 network policies
安装方法:
bash# Install Cilium in network policy only mode helm install cilium cilium/cilium --namespace kube-system \ --set enableIPv4Masquerade=false \ --set tunnel=disabled \ --set installIptablesRules=false \ --set autoDirectNodeRoutes=false \ --set policyEnforcementMode=default
Network Policy 示例:
# Default deny policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# Allow communication between specific applications
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080验证 Network Policy 实现:
# Verify network policy support
kubectl get pods -n kube-system | grep -E 'calico|cilium'
# Apply test network policy
kubectl apply -f test-network-policy.yaml
# Test connectivity
kubectl run -it --rm --restart=Never busybox --image=busybox -- wget -O- --timeout=2 http://service-name其他选项的问题:
- AWS security group 配置: AWS security groups 在 EC2 instance 级别工作,不能用于在 Kubernetes pods 之间实现细粒度 network policies。虽然 SecurityGroupsForPods 功能允许将 security groups 应用于 pods,但这是不同于 Kubernetes NetworkPolicy 的机制。
- AWS Network Firewall 设置: AWS Network Firewall 在 VPC 级别工作,不能用于在 Kubernetes pods 之间实现细粒度 network policies。
- 启用 VPC Flow Logs: VPC Flow Logs 用于监控和记录 network traffic,但不能用于实现 network policies。
Network policies 是控制 microservices 之间通信并增强 Kubernetes clusters 内部安全性的重要工具。要在 EKS 中实现 network policies,必须安装 Calico 或 Cilium 等额外 CNI plugins。
- 在 Amazon EKS cluster 中配置 Secrets 加密的正确方式是什么?
- A) 创建 EKS cluster 时使用 AWS KMS key 启用加密
- B) 将 Kubernetes Secrets 迁移到 AWS Secrets Manager
- C) 将所有 Secrets 编码为 Base64
- D) 将加密 sidecar container 部署到 EKS cluster
显示答案
答案:A) 创建 EKS cluster 时使用 AWS KMS key 启用加密
解释: 在 Amazon EKS cluster 中配置 Secrets 加密的正确方式,是在创建 EKS cluster 时或在现有 cluster 上使用 AWS KMS (Key Management Service) key 启用加密。此方法可确保 Kubernetes Secrets 存储在 etcd 中时被加密。
配置 EKS Secrets 加密的步骤:
创建 KMS Key 或使用现有 Key:
bash# Create KMS key aws kms create-key --description "EKS Secrets Encryption Key" # Store the created key ID KEY_ID=$(aws kms create-key --query KeyMetadata.KeyId --output text)创建新 Cluster 时启用加密:
bash# Enable encryption using AWS CLI aws eks create-cluster \ --name my-cluster \ --role-arn arn:aws:iam::123456789012:role/EksClusterRole \ --resources-vpc-config subnetIds=subnet-12345,subnet-67890 \ --encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:region:123456789012:key/'$KEY_ID'"}}]' # Enable encryption using eksctl cat > cluster.yaml << EOF apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster region: us-west-2 secretsEncryption: keyARN: arn:aws:kms:us-west-2:123456789012:key/$KEY_ID EOF eksctl create cluster -f cluster.yaml在现有 Cluster 上启用加密:
bash# For existing clusters, you cannot update the encryption configuration, so you need to create a new cluster and migrate workloads.验证加密配置:
bash# Check cluster information aws eks describe-cluster --name my-cluster --query cluster.encryptionConfig
使用加密的 Secrets:
启用加密后,创建和使用 Secrets 的方法不会改变。所有加密和解密都由 EKS control plane 自动处理。
# Create Secret
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4= # base64 encoded "admin"
password: cGFzc3dvcmQ= # base64 encoded "password"# Create Secret
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=password
# Verify Secret
kubectl get secret my-secret -o yaml配置 KMS Key 权限:
你需要配置适当的权限,使 EKS cluster 能够使用 KMS key:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEKSToUseKMSKey",
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}其他选项的问题:
- 将 Kubernetes Secrets 迁移到 AWS Secrets Manager: 这是一种可行方法,但它与标准 Kubernetes Secrets API 的兼容性较低,并且需要额外配置和集成。此外,所有应用都需要修改为从 AWS Secrets Manager 获取 secrets。
- 将所有 Secrets 编码为 Base64: Kubernetes Secrets 默认已经使用 Base64 编码。但是,Base64 是一种编码方式,不是加密,不能提供安全性。
- 将加密 sidecar container 部署到 EKS cluster: 这不是标准方法,并且向所有 pods 添加 sidecars 会引入复杂性。它还需要与 Kubernetes API server 集成。
使用 AWS KMS 的 EKS Secrets 加密是保护存储在 etcd 中的 Secrets 的最有效且集成度最高的方式。这让你可以保护静态敏感数据,并利用 AWS 强大的 key management 能力。
显示答案
答案:B) 创建 node group 时使用 --kubelet-extra-args 参数
解释: 自定义 Amazon EKS cluster 中 worker nodes 的 kubelet 配置的正确方式,是在创建 node group 时使用 --kubelet-extra-args 参数。此方法允许你在 node bootstrap 时向 kubelet 传递额外参数。
自定义 kubelet 配置的方法:
将 Launch Templates 与 Managed Node Groups 一起使用:
- 在 launch template 的 user data 部分自定义 bootstrap script。
bash#!/bin/bash set -o xtrace /etc/eks/bootstrap.sh my-cluster \ --kubelet-extra-args '--max-pods=110 --kube-reserved memory=0.3Gi,cpu=100m --system-reserved memory=0.5Gi,cpu=200m --eviction-hard memory.available<500Mi'使用 eksctl 创建 Node Groups:
# Create node group with kubelet arguments
eksctl create nodegroup \
--cluster my-cluster \
--name my-nodegroup \
--node-type m5.large \
--nodes 3 \
--kubelet-extra-args "--max-pods=110 --kube-reserved memory=0.3Gi,cpu=100m"使用 eksctl 配置文件:
yamlapiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster region: us-west-2 managedNodeGroups: - name: my-nodegroup instanceType: m5.large minSize: 2 maxSize: 5 kubeletExtraArgs: max-pods: "110" kube-reserved: "memory=0.3Gi,cpu=100m" system-reserved: "memory=0.5Gi,cpu=200m" eviction-hard: "memory.available<500Mi"为 self-managed node groups 使用 user data script:
bash#!/bin/bash set -o xtrace /etc/eks/bootstrap.sh my-cluster \ --kubelet-extra-args '--max-pods=110 --node-labels=node.kubernetes.io/role=worker,environment=prod'
常见自定义 kubelet 参数:
- max-pods:
- 设置每个 node 的最大 pods 数量
- 示例:
--max-pods=110
- node-labels:
- 向 node 添加 labels
- 示例:
--node-labels=environment=prod,node-type=worker
- kube-reserved:
- 为 Kubernetes system components 预留 resources
- 示例:
--kube-reserved=cpu=100m,memory=0.3Gi,ephemeral-storage=1Gi
- system-reserved:
- 为 OS system daemons 预留 resources
- 示例:
--system-reserved=cpu=100m,memory=0.5Gi,ephemeral-storage=1Gi
- eviction-hard:
- 设置 hard eviction 阈值
- 示例:
--eviction-hard=memory.available<500Mi,nodefs.available<10%
- cgroup-driver:
- 设置 cgroup driver
- 示例:
--cgroup-driver=systemd
如何验证配置:
# SSH into the node
ssh -i ~/.ssh/id_rsa ec2-user@<node-ip>
# Check kubelet service configuration
sudo systemctl status kubelet
sudo cat /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
# Check running kubelet process arguments
ps aux | grep kubelet其他选项的问题:
- 在 EKS console 中修改 cluster 配置: 虽然 EKS console 允许你修改 cluster 级别配置,但它不提供直接修改单个 nodes 的 kubelet 配置的选项。
- 使用 kubectl edit node 命令:
kubectl edit node命令可以修改 node object metadata,但不能更改 kubelet 配置。kubelet 配置作为 node OS 上的 service 运行,不能通过 Kubernetes API 直接修改。 - 使用 AWS Systems Manager 更改 node 配置: AWS Systems Manager 可用于在 nodes 上运行命令或更改配置,但此方法是在 nodes 已创建后应用的。此外,更改 kubelet 配置后必须重启 service,这可能影响正在运行的 pods。因此,在 node group 创建时配置更安全,也是推荐方法。
自定义 kubelet 配置允许你优化 node resource 管理、pod 密度、eviction policies 等,以满足 workload 需求。但是,这些更改可能影响 cluster 稳定性,因此应仔细测试。
- Amazon EKS clusters 中替代 Pod Security Policy 的推荐机制是什么?
- A) AWS Security Hub
- B) Pod Security Admission 或 Kyverno 等 policy engines
- C) AWS Config Rules
- D) EKS Security Groups
显示答案
答案:B) Pod Security Admission 或 Kyverno 等 policy engines
解释: 在 Amazon EKS clusters 中替代 Pod Security Policy (PSP) 的推荐机制是 Pod Security Admission 或 Kyverno 等 policy engines。从 Kubernetes 1.21 开始,PSP 被弃用,并在 Kubernetes 1.25 中被完全移除。Pod Security Admission 作为替代方案引入,也可以使用 Kyverno 或 OPA Gatekeeper 等 policy engines 作为替代。
Pod Security Admission:
Pod Security Admission 从 Kubernetes 1.23 开始作为 beta 功能引入,并在 1.25 版本中成为稳定功能。它是内置 Kubernetes 功能,提供三个安全级别(Privileged、Baseline、Restricted)。
配置方法:
yaml# Apply Pod Security standards to namespace apiVersion: v1 kind: Namespace metadata: name: my-namespace labels: pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/warn: restricted安全级别:
- Privileged: 无限制,允许所有功能
- Baseline: 防止已知的 privilege escalations
- Restricted: 强安全加固,应用最小权限原则
模式:
- enforce: 发生违规时拒绝创建 pod
- audit: 在 audit logs 中记录违规
- warn: 发生违规时显示 warning messages
Kyverno:
Kyverno 是 Kubernetes-native policy engine,使用基于 YAML 的 policies 来验证、变更和生成 cluster resources。
安装方法:
bash# Install Kyverno using Helm helm repo add kyverno https://kyverno.github.io/kyverno/ helm install kyverno kyverno/kyverno --namespace kyverno --create-namespacePolicy 示例:
yaml# Policy to prevent privileged containers apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: disallow-privileged-containers spec: validationFailureAction: enforce rules: - name: privileged-containers match: resources: kinds: - Pod validate: message: "Privileged containers are not allowed" pattern: spec: containers: - name: "*" securityContext: privileged: false
OPA Gatekeeper:
OPA (Open Policy Agent) Gatekeeper 是 Kubernetes 中另一个流行的 policy management 解决方案。
安装方法:
bash# Install Gatekeeper kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yamlPolicy 示例:
yaml# ConstraintTemplate definition apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spsprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spsprivilegedcontainer violation[{"msg": msg}] { c := input.review.object.spec.containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v", [c.name]) } # Apply Constraint apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: match: kinds: - apiGroups: [""] kinds: ["Pod"]
EKS 的实施建议:
- 启用 Pod Security Admission:
- 在 EKS 1.23 及以上版本中默认可用
- 向 namespaces 应用适当的 labels
- 安装 Kyverno 或 Gatekeeper:
- 当需要更复杂 policies 时
- 当需要对多种 resource types 应用 policies 时
- 逐步迁移:
- 从 PSP 逐步迁移到新解决方案
- 从 audit 模式开始识别问题,然后切换到 enforce 模式
其他选项的问题:
- AWS Security Hub: AWS Security Hub 是用于监控 AWS resources 安全态势的 service,但不能用于在 Kubernetes 中应用 pod 级别的 security policies。
- AWS Config Rules: AWS Config 是用于评估 AWS resource configurations 的 service,但不能用于在 Kubernetes 中应用 pod 级别的 security policies。
- EKS Security Groups: EKS Security Groups 用于控制 network traffic,不能用于限制 pod security contexts 或 privileges。
随着 Pod Security Policy (PSP) 被移除,EKS clusters 应使用 Pod Security Admission、Kyverno 或 OPA Gatekeeper 等替代机制来强化 pod 安全。这些工具可以限制 privileged containers、host namespace access、host path mounts 等。
7. 配置 IRSA (IAM Roles for Service Accounts) 以在 Amazon EKS cluster 中将 pod identity 与 AWS IAM 集成的第一步是什么? - A) 创建 IAM role - B) 创建 service account - C) 关联 OIDC provider - D) 修改 pod manifest
显示答案
答案:C) 关联 OIDC provider
解释: 在 Amazon EKS cluster 中配置 IRSA (IAM Roles for Service Accounts) 的第一步是关联 OIDC (OpenID Connect) provider。OIDC provider 是在 AWS IAM 与 Kubernetes service accounts 之间建立信任关系所必需的。这允许 Kubernetes service account tokens 成为 AWS IAM 中受信任的身份验证机制。
IRSA 配置步骤顺序:
关联 OIDC provider:
- 检查 EKS cluster 的 OIDC issuer URL
- 在 AWS IAM 中创建 OIDC provider
bash# Check OIDC issuer URL aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text # Example output: https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE # Associate OIDC provider eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve # Or use AWS CLI aws iam create-open-id-connect-provider \ --url https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE \ --thumbprint-list 9e99a48a9960b14926bb7f3b02e22da2b0ab7280 \ --client-id-list sts.amazonaws.com创建 IAM role:
- 创建 service account 将要 assume 的 IAM role
- 在 trust policy 中包含 OIDC provider 和 service account 条件
json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:my-service-account" } } } ] }创建 service account:
- 创建带有 IAM role ARN annotation 的 service account
yamlapiVersion: v1 kind: ServiceAccount metadata: name: my-service-account namespace: default annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-role修改 pod manifest:
- 在 pod manifest 中指定 service account
yamlapiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: my-service-account containers: - name: my-container image: my-image
使用 eksctl 简化 IRSA 设置:
eksctl 提供可自动完成上述所有步骤的命令:
# Associate OIDC provider
eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve
# Create service account and IAM role
eksctl create iamserviceaccount \
--name my-service-account \
--namespace default \
--cluster my-cluster \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve验证 IRSA 是否正常工作:
# Check service account
kubectl get serviceaccount my-service-account -o yaml
# Run test pod
kubectl run -it --rm \
--image amazon/aws-cli \
--serviceaccount my-service-account \
aws-cli -- s3 ls其他选项的问题:
- 创建 IAM role: 创建 IAM role 是 IRSA 配置的第二步。必须先关联 OIDC provider,这样 IAM role 的 trust policy 才能引用 OIDC provider。
- 创建 service account: 创建 service account 是 IRSA 配置的第三步。必须先创建 IAM role,这样才能将 IAM role ARN 作为 annotation 添加到 service account。
- 修改 pod manifest: 修改 pod manifest 是 IRSA 配置的最后一步。必须先创建 service account,这样 pod 才能引用该 service account。
IRSA 是一种安全且高效的方式,用于向 Kubernetes workloads 授予对 AWS services 的细粒度权限。这让你可以向每个应用只授予所需的最低权限,而不是共享 node 级别的 IAM roles。IRSA 配置的第一步是关联 OIDC provider,这对于建立 AWS IAM 与 Kubernetes service accounts 之间的信任关系至关重要。
- 在 Amazon EKS cluster 中启用 control plane logs 的正确方式是什么?
- A) 在 EKS control plane 上安装 CloudWatch agent
- B) 通过 AWS CLI 或 console 启用 cluster logging 配置
- C) 使用 Fluentd 配置 log forwarding
- D) SSH 到 EKS control plane nodes 修改 log 配置
显示答案
答案:B) 通过 AWS CLI 或 console 启用 cluster logging 配置
解释: 在 Amazon EKS cluster 中启用 control plane logs 的正确方式,是通过 AWS CLI 或 AWS Management Console 启用 cluster logging 配置。由于 EKS 是 managed service,control plane 由 AWS 管理,因此你无法直接访问它或安装 agents。相反,必须通过 AWS 提供的 APIs 配置 logging。
使用 AWS CLI 启用 control plane logs:
# Enable all log types
aws eks update-cluster-config \
--name my-cluster \
--region us-west-2 \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
# Enable only specific log types
aws eks update-cluster-config \
--name my-cluster \
--region us-west-2 \
--logging '{"clusterLogging":[{"types":["api","audit"],"enabled":true},{"types":["authenticator","controllerManager","scheduler"],"enabled":false}]}'使用 eksctl 启用 control plane logs:
# Enable all log types
eksctl utils update-cluster-logging \
--enable-types api,audit,authenticator,controllerManager,scheduler \
--cluster my-cluster \
--region us-west-2
# Enable only specific log types
eksctl utils update-cluster-logging \
--enable-types api,audit \
--disable-types authenticator,controllerManager,scheduler \
--cluster my-cluster \
--region us-west-2使用 AWS Management Console 启用 control plane logs:
- 登录 AWS Management Console。
- 导航到 EKS service。
- 从 cluster 列表中选择目标 cluster。
- 选择 "Logging" tab。
- 点击 "Manage"。
- 选择要启用的 log types:
- API server (api)
- Audit (audit)
- Authenticator (authenticator)
- Controller manager (controllerManager)
- Scheduler (scheduler)
- 点击 "Save changes"。
可用的 log types:
- API server (api):
- 来自 Kubernetes API server 的 logs
- 包含 API request 和 response 信息
- Audit (audit):
- cluster 中所有活动的 audit logs
- 对安全和合规目的很重要
- Authenticator (authenticator):
- 来自 AWS IAM Authenticator 的 logs
- 有助于排查身份验证问题
- Controller manager (controllerManager):
- 来自 Kubernetes controller manager 的 logs
- 包含 resource state management 信息
- Scheduler (scheduler):
- 来自 Kubernetes scheduler 的 logs
- 包含 pod scheduling 决策信息
如何查看 logs:
启用的 logs 存储在 CloudWatch Logs 中,可以在以下 log group 中查看:
/aws/eks/my-cluster/cluster每种 log type 都作为单独的 log stream 存储:
kube-apiserver-xxxxx
audit-xxxxx
authenticator-xxxxx
kube-controller-manager-xxxxx
kube-scheduler-xxxxx成本注意事项:
- Control plane logs 受 CloudWatch Logs pricing 约束。
- 启用所有 log types 可能会生成大量 logs。
- 为优化成本,建议只选择性启用所需的 log types。
- 可以通过设置适当的 log retention periods 来管理成本。
其他选项的问题:
- 在 EKS control plane 上安装 CloudWatch agent: EKS control plane 由 AWS 管理,因此你无法直接访问它或安装 agents。
- 使用 Fluentd 配置 log forwarding: Fluentd 可用于收集 worker nodes 的 logs,但不能访问 EKS control plane logs。
- SSH 到 EKS control plane nodes 修改 log 配置: EKS control plane nodes 由 AWS 管理,因此你不能直接 SSH 进入它们。
EKS control plane logs 为 cluster troubleshooting、security audits 和 compliance 提供重要信息。你可以通过 AWS CLI 或 AWS Management Console 选择性启用所需的 log types 来有效监控。
- 更改 Amazon EKS cluster 中 node group instance type 的正确方式是什么?
- A) 在 AWS Management Console 中直接修改 node group instance type
- B) 使用新的 instance type 创建新 node group 并迁移 workloads
- C) 使用 kubectl edit 命令修改 node specifications
- D) 使用 AWS CLI update-nodegroup-config 命令
显示答案
答案:B) 使用新的 instance type 创建新 node group 并迁移 workloads
解释: 更改 Amazon EKS cluster 中 node group instance type 的正确方式,是使用新的 instance type 创建新的 node group,然后迁移 workloads。在 EKS managed node groups 中,创建后无法直接更改 instance type,因此必须创建新的 node group、迁移 workloads,然后删除现有 node group。
更改 node group instance type 的步骤:
创建新 node group:
bash# Create new node group using eksctl eksctl create nodegroup \ --cluster my-cluster \ --name my-new-nodegroup \ --node-type m5.large \ --nodes 3 \ --nodes-min 1 \ --nodes-max 5 \ --node-labels "migration-target=true"
Create new node group using AWS CLI
aws eks create-nodegroup
--cluster-name my-cluster
--nodegroup-name my-new-nodegroup
--subnets subnet-12345 subnet-67890
--instance-types m5.large
--scaling-config minSize=1,maxSize=5,desiredSize=3
--node-role arn:aws:iam::123456789012:role/EksNodeRole
--labels migration-target=true
2. **验证新 node group 状态**:
```bash
# Check node group status
aws eks describe-nodegroup \
--cluster-name my-cluster \
--nodegroup-name my-new-nodegroup \
--query "nodegroup.status"
# Check nodes
kubectl get nodes --label-columns migration-target迁移 workloads:
方法 1:使用 Cordoning 和 Draining
bash# Identify nodes in the existing node group OLD_NODES=$(kubectl get nodes -l alpha.eksctl.io/nodegroup-name=my-old-nodegroup -o jsonpath='{.items[*].metadata.name}') # Cordon nodes (prevent new pod scheduling) for node in $OLD_NODES; do kubectl cordon $node done # Drain nodes (remove existing pods) for node in $OLD_NODES; do kubectl drain $node --ignore-daemonsets --delete-emptydir-data done方法 2:使用 Pod Selector
yaml# Deploy to new nodes using node selector apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: nodeSelector: migration-target: "true"方法 3:Blue/Green Deployment
- 将新的 deployment version 部署到新 node group
- 逐步将 traffic 切换到新 version
- 移除现有 deployment version
删除现有 node group:
bash# Delete node group using eksctl eksctl delete nodegroup \ --cluster my-cluster \ --name my-old-nodegroup # Delete node group using AWS CLI aws eks delete-nodegroup \ --cluster-name my-cluster \ --nodegroup-name my-old-nodegroup
迁移期间的注意事项:
最小化 workload 中断:
- 配置 PodDisruptionBudget
yamlapiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb spec: minAvailable: 2 # or maxUnavailable: 1 selector: matchLabels: app: my-app- 使用 rolling update strategy
Resource 需求:
- 验证新 instance type 是否满足 workload 需求
- 考虑 CPU、memory、storage 和 networking 需求
Stateful workloads:
- 验证使用 persistent volumes 的 workloads 的数据持久性
- 必要时执行 backups
成本影响:
- 评估新 instance type 的成本影响
- 迁移期间两个 node groups 同时运行,成本会暂时增加
其他选项的问题:
- 在 AWS Management Console 中直接修改 node group instance type: 在 EKS managed node groups 中,创建后不能直接修改 instance type。
- 使用 kubectl edit 命令修改 node specifications: kubectl 用于修改 Kubernetes API objects,但 node 的底层 instance type 在 AWS infrastructure 级别确定,不能通过 kubectl 更改。
- 使用 AWS CLI update-nodegroup-config 命令:
update-nodegroup-config命令可以修改 node group 的 scaling configuration、labels、taints 等,但不能更改 instance type。
为了优化 cluster 性能、降低成本或满足新的 workload 需求,可能需要更改 node group 的 instance type。创建新 node group 并迁移 workloads 是在尽量减少中断的同时安全更改 instance types 的推荐方法。
10. 在 Amazon EKS cluster 中将 Kubernetes taints 应用于 node group 的正确方式是什么? - A) 使用 kubectl taint 命令 - B) 创建 node group 时使用 --taints 参数 - C) 在 AWS Management Console 中配置 node group taints - D) 在 node bootstrap script 中修改 kubelet 配置
显示答案
答案:B) 创建 node group 时使用 --taints 参数
解释: 在 Amazon EKS cluster 中将 Kubernetes taints 应用于 node group 的正确方式,是在创建 node group 时使用 --taints 参数。EKS managed node groups 提供在创建时或更新期间配置 taints 的能力。使用此方法可确保 taints 一致地应用到 node group 中的所有 nodes,并在 nodes 被替换时保持。
使用 eksctl 配置 taints:
# Create node group with taints
eksctl create nodegroup \
--cluster my-cluster \
--name tainted-ng \
--node-type m5.large \
--nodes 3 \
--taints "dedicated=gpu:NoSchedule,special=true:PreferNoSchedule"
# Configure taints using configuration file
cat > nodegroup.yaml << EOF
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: my-cluster
region: us-west-2
managedNodeGroups:
- name: tainted-ng
instanceType: m5.large
minSize: 2
maxSize: 5
taints:
- key: dedicated
value: gpu
effect: NoSchedule
- key: special
value: "true"
effect: PreferNoSchedule
EOF
eksctl create nodegroup -f nodegroup.yaml使用 AWS CLI 配置 taints:
# Create node group with taints
aws eks create-nodegroup \
--cluster-name my-cluster \
--nodegroup-name tainted-ng \
--subnets subnet-12345 subnet-67890 \
--instance-types m5.large \
--scaling-config minSize=2,maxSize=5,desiredSize=3 \
--node-role arn:aws:iam::123456789012:role/EksNodeRole \
--taints "key=dedicated,value=gpu,effect=NoSchedule" "key=special,value=true,effect=PreferNoSchedule"
# Update taints on existing node group
aws eks update-nodegroup-config \
--cluster-name my-cluster \
--nodegroup-name tainted-ng \
--taints "addOrUpdateTaints=[{key=dedicated,value=gpu,effect=NoSchedule}],removeTaints=[{key=special}]"使用 AWS Management Console 配置 taints:
- 登录 AWS Management Console。
- 导航到 EKS service。
- 选择 cluster。
- 选择 "Compute" tab。
- 点击 "Add node group"。
- 输入 node group details。
- 在 "Kubernetes taints" 部分,点击 "Add taint"。
- 输入 key、value 和 effect。
- 点击 "Create"。
Taint effect 类型:
- NoSchedule:
- 没有匹配 toleration 的 Pods 不会被调度到该 node。
- 现有 pods 不受影响。
- PreferNoSchedule:
- 没有匹配 toleration 的 Pods 最好不要被调度到该 node,但不保证。
- 如果它们无法调度到其他 nodes,则可能会被调度到此 node。
- NoExecute:
- 没有匹配 toleration 的 Pods 不会被调度到该 node。
- 已经运行但没有匹配该 taint 的 toleration 的 Pods 将被 evicted。
taints 的常见使用场景:
隔离特殊硬件 nodes:
bash# Apply taint to GPU nodes eksctl create nodegroup \ --cluster my-cluster \ --name gpu-nodes \ --node-type p3.2xlarge \ --taints "dedicated=gpu:NoSchedule" # Add toleration to GPU workload apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule" containers: - name: gpu-container image: gpu-image准备 node maintenance:
bash# Apply taint to node kubectl taint nodes node1 maintenance=planned:NoSchedule # Remove taint after maintenance kubectl taint nodes node1 maintenance=planned:NoSchedule-为特定 workloads 配置 dedicated nodes:
bash# Node group dedicated to production workloads eksctl create nodegroup \ --cluster my-cluster \ --name prod-nodes \ --node-type m5.large \ --taints "environment=production:NoSchedule" # Add toleration to production deployment apiVersion: apps/v1 kind: Deployment metadata: name: prod-app spec: template: spec: tolerations: - key: "environment" operator: "Equal" value: "production" effect: "NoSchedule"
其他选项的问题:
- 使用 kubectl taint 命令: 你可以使用
kubectl taint命令向单个 nodes 应用 taints,但这是临时更改,nodes 被替换时 taints 不会保持。它也难以一致地应用到 node group 中的所有 nodes。 - 在 AWS Management Console 中配置 node group taints: 你也可以在 AWS Management Console 中创建 node group 时配置 taints,但这与“创建 node group 时使用 --taints 参数”是同一种方法。因此,该选项也可能是正确答案,但从技术上讲,它与创建 node group 时配置 taints 相同。
- 在 node bootstrap script 中修改 kubelet 配置: 你可以在 bootstrap script 中使用
--register-with-taintsflag 修改 kubelet 配置,但这种方法复杂且容易出错。对于 EKS managed node groups 也不推荐使用。
Taints 是一个有用的 Kubernetes 功能,可用于只将特定 workloads 部署到特定 nodes,或将某些 workloads 从特定 nodes 排除。对于 EKS managed node groups,在创建或更新 node group 时配置 taints 是最有效且最易管理的方法。
练习 1:配置 IRSA (IAM Roles for Service Accounts)
场景: 你有一个运行在 EKS cluster 中的应用,需要访问 S3 bucket。遵循安全最佳实践,你希望使用 IRSA 只向特定 pods 授予必要权限,而不是共享 node IAM role。
要求:
- 关联 OIDC provider
- 创建具有 S3 访问权限的 IAM role
- 创建 service account 并关联 IAM role
- 部署使用该 service account 的 pod
- 测试 S3 访问
解答:
显示解答
1. 关联 OIDC Provider
# Get the cluster's OIDC issuer URL
OIDC_PROVIDER=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
# Check if OIDC provider already exists
aws iam list-open-id-connect-providers | grep $OIDC_PROVIDER
# Create OIDC provider if it doesn't exist
eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve2. 创建具有 S3 访问权限的 IAM Role
# Create trust policy
cat > trust-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:sub": "system:serviceaccount:default:s3-access-sa"
}
}
}
]
}
EOF
# Create IAM role
aws iam create-role --role-name s3-access-role --assume-role-policy-document file://trust-policy.json
# Attach S3 access policy
aws iam attach-role-policy --role-name s3-access-role --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess3. 创建 Service Account 并关联 IAM Role
# Get IAM role ARN
ROLE_ARN=$(aws iam get-role --role-name s3-access-role --query Role.Arn --output text)
# Create service account
cat > service-account.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-access-sa
namespace: default
annotations:
eks.amazonaws.com/role-arn: ${ROLE_ARN}
EOF
kubectl apply -f service-account.yaml4. 部署使用该 Service Account 的 Pod
# Deploy test pod
cat > pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: s3-access-pod
namespace: default
spec:
serviceAccountName: s3-access-sa
containers:
- name: aws-cli
image: amazon/aws-cli:latest
command:
- sleep
- "3600"
restartPolicy: Never
EOF
kubectl apply -f pod.yaml5. 测试 S3 访问
# Verify the pod is running
kubectl get pod s3-access-pod
# Test listing S3 buckets
kubectl exec -it s3-access-pod -- aws s3 ls
# Test listing objects in a specific S3 bucket
kubectl exec -it s3-access-pod -- aws s3 ls s3://my-bucket
# Verify AWS credentials
kubectl exec -it s3-access-pod -- aws sts get-caller-identity6. 清理
# Delete pod
kubectl delete pod s3-access-pod
# Delete service account
kubectl delete serviceaccount s3-access-sa
# Clean up IAM role
aws iam detach-role-policy --role-name s3-access-role --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
aws iam delete-role --role-name s3-access-role补充说明:
- OIDC Provider 关联:
- OIDC provider 在 AWS IAM 与 Kubernetes service accounts 之间建立信任关系。
- 每个 cluster 只需要设置一次。
- IAM Role Trust Policy:
- trust policy 限制只有特定 namespaces 中的特定 service accounts 可以 assume 该 role。
- 使用 condition statements 增强安全性。
- Service Account Annotation:
eks.amazonaws.com/role-arnannotation 指定 service account 将 assume 的 IAM role。- 此 annotation 由 EKS Pod Identity Webhook 处理。
- Environment Variables:
- EKS Pod Identity Webhook 会自动将以下 environment variables 注入 pod:
AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILEAWS_REGION
- AWS SDKs 使用这些 environment variables 获取 credentials。
- EKS Pod Identity Webhook 会自动将以下 environment variables 注入 pod:
- 最小权限原则:
- 只授予应用所需的最低权限。
- 在此示例中,只授予了 S3 read-only access 权限。
通过本练习,你学习了如何配置 IRSA,将对 AWS services 的细粒度权限只授予运行在 EKS cluster 中的特定 pods。这种方法比共享 node IAM role 更安全,并遵循最小权限原则。
### 练习 2:强化 EKS Cluster 安全
场景: 你是公司的安全工程师,需要强化新创建的 EKS cluster 的安全。该 cluster 已使用默认设置创建并配置。你希望根据安全最佳实践加固 cluster。
要求:
- 限制 cluster endpoint access
- 启用 Secrets encryption
- 实现 network policies
- 应用 Pod Security Standards
- 启用 control plane logging
解答:
显示解答
1. 限制 Cluster Endpoint Access
# Check current cluster endpoint configuration
aws eks describe-cluster --name my-cluster --query "cluster.resourcesVpcConfig.endpointPublicAccess"
aws eks describe-cluster --name my-cluster --query "cluster.resourcesVpcConfig.endpointPrivateAccess"
# Restrict public access (allow only specific CIDR blocks)
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config endpointPublicAccess=true,endpointPrivateAccess=true,publicAccessCidrs=["203.0.113.0/24","198.51.100.0/24"]
# Or disable public access (private cluster)
aws eks update-cluster-config \
--name my-cluster \
--resources-vpc-config endpointPublicAccess=false,endpointPrivateAccess=true2. 启用 Secrets Encryption
# Create KMS key
aws kms create-key --description "EKS Secrets Encryption Key"
KEY_ID=$(aws kms create-key --query KeyMetadata.KeyId --output text)
# Add alias to KMS key
aws kms create-alias \
--alias-name alias/eks-secrets \
--target-key-id $KEY_ID
# Cannot enable encryption on current cluster, so a new cluster must be created
# Get existing cluster configuration
aws eks describe-cluster --name my-cluster > cluster-config.json
# Create new cluster (more parameters are needed in practice)
aws eks create-cluster \
--name my-cluster-encrypted \
--role-arn $(aws eks describe-cluster --name my-cluster --query cluster.roleArn --output text) \
--resources-vpc-config subnetIds=$(aws eks describe-cluster --name my-cluster --query cluster.resourcesVpcConfig.subnetIds --output text | tr -d '[]" ' | tr ',' ' '),securityGroupIds=$(aws eks describe-cluster --name my-cluster --query cluster.resourcesVpcConfig.securityGroupIds --output text | tr -d '[]" ') \
--encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:'$(aws configure get region)':'$(aws sts get-caller-identity --query Account --output text)':key/'$KEY_ID'"}}]'3. 实现 Network Policies
# Install Calico
kubectl create namespace tigera-operator
helm repo add projectcalico https://docs.projectcalico.org/charts
helm install calico projectcalico/tigera-operator --namespace tigera-operator
# Create default deny network policy
cat > default-deny.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
kubectl apply -f default-deny.yaml
# Policy to allow communication between specific applications
cat > allow-app-communication.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
EOF
kubectl apply -f allow-app-communication.yaml4. 应用 Pod Security Standards
# Apply Pod Security Standards to namespace
cat > pod-security.yaml << EOF
apiVersion: v1
kind: Namespace
metadata:
name: restricted-ns
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
EOF
kubectl apply -f pod-security.yaml
# Add labels to existing namespace
kubectl label namespace default \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
# Install Kyverno (for additional policy enforcement)
kubectl create namespace kyverno
helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno --namespace kyverno
# Policy to prevent privileged containers
cat > restrict-privileged.yaml << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
spec:
validationFailureAction: enforce
rules:
- name: privileged-containers
match:
resources:
kinds:
- Pod
validate:
message: "Privileged containers are not allowed"
pattern:
spec:
containers:
- name: "*"
securityContext:
privileged: false
EOF
kubectl apply -f restrict-privileged.yaml5. 启用 Control Plane Logging
# Enable all control plane log types
aws eks update-cluster-config \
--name my-cluster \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
# Verify logging status
aws eks describe-cluster --name my-cluster --query "cluster.logging"
# Check logs in CloudWatch Logs
aws logs describe-log-groups --log-group-name-prefix /aws/eks/my-cluster6. 其他安全加固措施
# Restrict IAM policy for AWS Load Balancer Controller
cat > alb-controller-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeListeners"
],
"Resource": "*"
}
]
}
EOF
aws iam create-policy \
--policy-name EksAlbControllerRestrictedPolicy \
--policy-document file://alb-controller-policy.json
# Configure node group update for periodic node replacement
aws eks update-nodegroup-config \
--cluster-name my-cluster \
--nodegroup-name my-nodegroup \
--update-config '{"maxUnavailable": 1}'
# Start node group update
aws eks update-nodegroup-version \
--cluster-name my-cluster \
--nodegroup-name my-nodegroup安全加固说明:
- 限制 Cluster Endpoint Access:
- 将 public endpoint access 限制为特定 IP ranges,或完全禁用。
- 启用 private endpoint 以允许从 VPC 内部访问 cluster。
- 这可以防止未经授权访问 cluster API server。
- 启用 Secrets Encryption:
- 使用 AWS KMS keys 加密存储在 etcd 中的 Kubernetes Secrets。
- 保护静态敏感数据。
- 注意:无法在现有 clusters 上启用加密,因此需要创建新 cluster。
- 实现 Network Policies:
- 安装 Calico 以支持 Kubernetes network policies。
- 应用 default deny policies 以阻止所有未明确允许的 traffic。
- 实现只允许必要通信的细粒度 policies。
- 应用 Pod Security Standards:
- 应用 Kubernetes 1.23 及更高版本中可用的 Pod Security Standards。
- 在 namespace 级别设置 security constraints。
- 使用 Kyverno 等 policy engines 应用额外 security policies。
- 启用 Control Plane Logging:
- 将所有 control plane log types 发送到 CloudWatch Logs。
- 通过 audit logs 监控 cluster 活动。
- 保留 logs 以用于 security events 和 troubleshooting。
通过本动手练习,你学习了多种强化 EKS cluster 安全的方法。这些安全措施有助于提升 cluster 的安全态势,并保护它免受未经授权访问和恶意活动影响。
以下是关于 Amazon EKS cluster 创建高级主题的问题。本节测试你对 EKS cluster 创建中的高级概念和最佳实践的理解。
- 以下哪一项不是在 Amazon EKS cluster 中配置 IPv6 支持的要求?
- A) 分配了 IPv6 CIDR block 的 VPC
- B) 支持 IPv6 的 CNI plugin 版本
- C) Dual-stack subnets
- D) IPv6-only instance types
显示答案
答案:D) IPv6-only instance types
解释: “IPv6-only instance types”不是在 Amazon EKS cluster 中配置 IPv6 支持的要求。IPv6 支持不需要特殊 instance types,因为大多数 EC2 instance types 都支持 IPv6。实际要求是分配了 IPv6 CIDR block 的 VPC、支持 IPv6 的 CNI plugin 版本,以及 dual-stack subnets。
EKS 中 IPv6 支持的实际要求:
分配了 IPv6 CIDR block 的 VPC:
- 必须向你的 VPC 分配 IPv6 CIDR block。
- 可以通过 AWS Management Console 或 AWS CLI 配置。
bash# Assign IPv6 CIDR block to existing VPC aws ec2 associate-vpc-cidr-block \ --vpc-id vpc-12345 \ --amazon-provided-ipv6-cidr-block支持 IPv6 的 CNI plugin 版本:
- 需要 Amazon VPC CNI plugin 版本 1.10.0 或更高版本。
- 需要进行 IPv6 支持配置。
bash# Check CNI version kubectl describe daemonset aws-node --namespace kube-system | grep Image # Update CNI kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.10.0/config/master/aws-k8s-cni.yaml # Enable IPv6 kubectl set env daemonset aws-node -n kube-system ENABLE_IPV6=trueDual-stack subnets:
- Subnets 必须同时分配 IPv4 和 IPv6 CIDR blocks。
- 必须在 route table 中配置 IPv6 routing。
bash# Assign IPv6 CIDR block to subnet aws ec2 associate-subnet-cidr-block \ --subnet-id subnet-12345 \ --ipv6-cidr-block 2600:1f16:d93:e900::/64 # Create IPv6 internet gateway aws ec2 create-egress-only-internet-gateway --vpc-id vpc-12345
创建 EKS IPv6 Cluster:
# Create IPv6 cluster using eksctl
cat > ipv6-cluster.yaml << EOF
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ipv6-cluster
region: us-west-2
version: '1.23'
vpc:
id: vpc-12345
subnets:
private:
us-west-2a:
id: subnet-12345
us-west-2b:
id: subnet-67890
clusterEndpoints:
publicAccess: true
privateAccess: true
kubernetesNetworkConfig:
ipFamily: IPv6
managedNodeGroups:
- name: ng-1
instanceType: m5.large
desiredCapacity: 2
EOF
eksctl create cluster -f ipv6-cluster.yaml验证 IPv6 Cluster 配置:
# Check cluster information
aws eks describe-cluster --name ipv6-cluster --query "cluster.kubernetesNetworkConfig"
# Verify Pod IP assignment
kubectl get pods -o wide
# Verify Service IP assignment
kubectl get services -o wideIPv6 Clusters 的特征:
- Pod IP 分配:
- Pods 仅分配 IPv6 addresses。
- cluster 内部通信通过 IPv6 进行。
- Service IP 分配:
- ClusterIP services 使用 IPv6 addresses。
- 默认 service CIDR 是 fd00::/108。
- DNS 配置:
- CoreDNS 配置为使用 IPv6 addresses。
- 可通过 AAAA records 进行 service name resolution。
- 外部通信:
- Internet 通信需要 Egress-Only Internet Gateway。
- 入站通信需要启用 IPv6 的 load balancer。
使用 IPv6 的优势:
- 解决 IP Address Exhaustion:
- 克服 IPv4 address space 的限制。
- 解决大规模 clusters 中的 IP address shortage 问题。
- 简化 Networking:
- 无需 NAT,简化 network 配置。
- Direct routing 可以提升 network performance。
- 未来兼容性:
- 为向 IPv6-only environments 过渡做准备。
- 支持利用新的 networking features 和 optimizations。
“IPv6-only instance types”是一个不存在的概念,大多数 EC2 instance types 都支持 IPv6。在 EKS 中配置 IPv6 不需要选择特殊 instance types。
2. 配置 Amazon EKS cluster 中 custom networking 的主要好处是什么? - A) 将 Pod IP address range 与 VPC CIDR 分离以防止 IP address conflicts - B) 缩短 cluster 创建时间 - C) 提高 control plane 性能 - D) 加密 node-to-node 通信
显示答案
答案:A) 将 Pod IP address range 与 VPC CIDR 分离以防止 IP address conflicts
解释: 在 Amazon EKS cluster 中配置 custom networking 的主要好处,是将 Pod IP address range 与 VPC CIDR 分离,以防止 IP address conflicts。此功能便于与现有 network infrastructure 集成,并在大规模 clusters 中实现更高效的 IP address management。
Custom Networking 的工作方式:
默认情况下,Amazon VPC CNI plugin 从 node 的主 network interface 分配 secondary IP addresses,为 Pods 提供 IP addresses。在这种方法中,Pod IP addresses 从 VPC CIDR range 内分配。相比之下,custom networking 允许你从与 VPC CIDR 分离的 CIDR block 中分配 Pod IP addresses。
配置 Custom Networking 的步骤:
启用 Custom Networking:
bash# Modify CNI plugin configuration kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true创建 ENIConfig Resources:
yaml# Create ENIConfig for each availability zone apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: us-west-2a spec: subnet: subnet-12345 securityGroups: - sg-12345 --- apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: us-west-2b spec: subnet: subnet-67890 securityGroups: - sg-12345启用基于 Availability Zone 的 ENIConfig 使用方式:
bashkubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=topology.kubernetes.io/zone验证 Node Labels:
bashkubectl get nodes --show-labels | grep topology.kubernetes.io/zone
Custom Networking 的优势:
- 防止 IP Address Conflicts:
- 将 Pod IP address range 与 VPC CIDR 分离,以防止 IP address conflicts。
- 便于与现有 network infrastructure 集成。
- 对 on-premises networks 与 VPCs 之间的 peering 或 VPN connections 很有用。
- IP Address Management 的灵活性:
- 允许单独规划和管理 Pod IP address ranges。
- 在大规模 clusters 中实现更高效的 IP address management。
- Network Segmentation:
- 通过将 Pods 放置在特定 subnets 中实现 network segmentation。
- 可通过 security groups 进行 network access control。
- Multi-CIDR Support:
- 可使用多个 CIDR blocks 扩展 IP address space。
- 即使现有 VPC CIDR 有限,也可以构建大规模 clusters。
Custom Networking 的使用场景:
- Hybrid Network Environments:
- 当 on-premises networks 与 AWS VPC 之间存在连接时
- 当必须防止 IP address space 重叠时
- 大规模 Clusters:
- 当运行大量 Pods 时
- 当 VPC CIDR range 有限时
- 多租户环境:
- 当每个 tenant 都需要单独 subnets 时
- 当需要 network isolation 时
- 监管要求:
- 当法规要求将特定 workloads 放置在特定 subnets 中时
其他选项的问题:
- 缩短 cluster 创建时间: Custom networking 不会影响 cluster 创建时间,并且由于额外配置,实际上可能增加设置时间。
- 提高 control plane 性能: Custom networking 只影响 data plane(worker nodes 和 Pods)networking,不会直接影响 control plane 性能。
- 加密 node-to-node 通信: Custom networking 只改变 IP addresses 的分配方式,与 node-to-node 通信加密无关。Node-to-node 通信加密必须通过单独的安全机制实现(例如 Calico、Cilium encryption features)。
Custom networking 是一项强大功能,可以更灵活地配置 EKS cluster networking,但其配置复杂,并可能带来额外的管理开销,因此只有在确实需要时才应使用。
3. 以下哪一项不是在 Amazon EKS cluster 中支持 Windows worker nodes 的要求? - A) 需要至少 2 个基于 Amazon Linux 的 managed node groups - B) 安装 VPC-CNI、kube-proxy、CoreDNS add-ons - C) Windows Server 2019 或更高版本 AMI - D) Cluster 版本 1.14 或更高
显示答案
答案:A) 需要至少 2 个基于 Amazon Linux 的 managed node groups
解释: 要在 Amazon EKS cluster 中支持 Windows worker nodes,需要至少 1 个(不是 2 个或更多)基于 Amazon Linux 的 managed node group。这是因为 CoreDNS 等关键 system Pods 必须运行在 Linux nodes 上。但是,要求至少 2 个 Linux node groups 是不正确的。
EKS 中 Windows Worker Node 支持的实际要求:
需要 Linux Node Group:
- cluster 中至少需要 1 个 Linux node。
- CoreDNS、VPC CNI plugin 和 kube-proxy 等 System Pods 只在 Linux nodes 上运行。
bash# Create Linux node group eksctl create nodegroup \ --cluster my-cluster \ --name linux-ng \ --node-type m5.large \ --nodes 2安装 VPC-CNI、kube-proxy、CoreDNS Add-ons:
- 这些 add-ons 是 EKS cluster 的关键组件。
- Windows node 支持可能需要特定版本或更高版本。
bash# Check add-on versions aws eks describe-addon-versions \ --addon-name vpc-cni \ --kubernetes-version 1.23 # Update add-on aws eks update-addon \ --cluster-name my-cluster \ --addon-name vpc-cni \ --addon-version v1.10.4-eksbuild.1Windows Server 2019 或更高版本 AMI:
- Windows worker nodes 必须使用 Windows Server 2019 或更高版本 AMI。
- 建议使用 EKS-optimized Windows AMI。
bash# Create Windows node group eksctl create nodegroup \ --cluster my-cluster \ --name windows-ng \ --node-type m5.large \ --nodes 2 \ --node-ami-family WindowsServer2019FullContainerCluster 版本 1.14 或更高:
- Windows node 支持从 Kubernetes 1.14 开始正式支持。
- 建议使用更高版本以获得最新功能。
bash# Check cluster version aws eks describe-cluster --name my-cluster --query "cluster.version"
启用 Windows 支持的步骤:
启用 Windows 支持:
bash# Enable Windows support kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/vpc-resource-controller.yaml kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/vpc-admission-webhook.yaml创建 Windows Node Group:
bash# Create Windows node group using eksctl eksctl create nodegroup \ --cluster my-cluster \ --name windows-ng \ --node-type m5.large \ --nodes 2 \ --node-ami-family WindowsServer2019FullContainer验证 Windows Nodes:
bash# Verify nodes kubectl get nodes -o wide # Verify Windows node labels kubectl get nodes -l kubernetes.io/os=windows
Windows Container Deployment 示例:
# Windows Pod deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: windows-server-iis
spec:
selector:
matchLabels:
app: windows-server-iis
tier: backend
track: stable
replicas: 2
template:
metadata:
labels:
app: windows-server-iis
tier: backend
track: stable
spec:
nodeSelector:
kubernetes.io/os: windows
containers:
- name: windows-server-iis
image: mcr.microsoft.com/windows/servercore:ltsc2019
ports:
- containerPort: 80
command:
- powershell.exe
- -command
- "Add-WindowsFeature Web-Server; Invoke-WebRequest -UseBasicParsing -Uri 'https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.6/ServiceMonitor.exe' -OutFile 'C:\\ServiceMonitor.exe'; echo '<html><body><br/><br/><center><h1>Hello from Windows Container</h1></center></body></html>' > C:\\inetpub\\wwwroot\\default.html; C:\\ServiceMonitor.exe 'w3svc';"Windows Node 限制:
- Networking 限制:
- Windows nodes 不支持 HostPort 和 HostNetwork 模式。
- Windows nodes 不支持 NodeLocal DNSCache。
- Storage 限制:
- Windows nodes 仅支持某些 storage drivers。
- host path volume mounts 存在限制。
- Container Runtime:
- Windows nodes 仅支持 containerd runtime。
- Linux containers 不能在 Windows nodes 上运行。
- 功能限制:
- 某些 Kubernetes features 在 Windows nodes 上不受支持。
- privileged containers、process namespace sharing 等存在限制。
要在 EKS 中支持 Windows worker nodes,至少需要一个 Linux node group,但不强制要求两个或更多 Linux node groups。因此,“需要至少 2 个基于 Amazon Linux 的 managed node groups”不是准确的要求。
3. 以下哪一项不是在 Amazon EKS cluster 中支持 Windows worker nodes 的要求? - A) 需要至少 2 个基于 Amazon Linux 的 managed node groups - B) 安装 VPC-CNI、kube-proxy、CoreDNS add-ons - C) 使用 Windows Server 2019 或更高版本 AMI - D) Cluster 版本 1.14 或更高
显示答案
答案:A) 需要至少 2 个基于 Amazon Linux 的 managed node groups
解释: 要在 Amazon EKS cluster 中支持 Windows worker nodes,需要至少一个(不是两个或更多)基于 Amazon Linux 的 managed node group。这是因为 CoreDNS 等关键 system pods 必须运行在 Linux nodes 上。但是,要求至少两个 Linux node groups 并不准确。
EKS 中 Windows Worker Node 支持的实际要求:
需要 Linux Node Group:
- cluster 至少需要一个 Linux node。
- CoreDNS、VPC CNI plugin 和 kube-proxy 等 system pods 只在 Linux nodes 上运行。
bash# Create Linux node group eksctl create nodegroup \ --cluster my-cluster \ --name linux-ng \ --node-type m5.large \ --nodes 2安装 VPC-CNI、kube-proxy、CoreDNS Add-ons:
- 这些 add-ons 是 EKS cluster 的基础组件。
- Windows node 支持可能需要特定版本或更高版本。
bash# Check add-on versions aws eks describe-addon-versions \ --addon-name vpc-cni \ --kubernetes-version 1.23 # Update add-on aws eks update-addon \ --cluster-name my-cluster \ --addon-name vpc-cni \ --addon-version v1.10.4-eksbuild.1使用 Windows Server 2019 或更高版本 AMI:
- Windows worker nodes 必须使用 Windows Server 2019 或更高版本 AMI。
- 建议使用 EKS-optimized Windows AMI。
bash# Create Windows node group eksctl create nodegroup \ --cluster my-cluster \ --name windows-ng \ --node-type m5.large \ --nodes 2 \ --node-ami-family WindowsServer2019FullContainerCluster 版本 1.14 或更高:
- Windows node 支持从 Kubernetes 1.14 开始 generally available。
- 建议使用更高版本以获得最新功能。
bash# Check cluster version aws eks describe-cluster --name my-cluster --query "cluster.version"
启用 Windows 支持的步骤:
启用 Windows 支持:
bash# Enable Windows support kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/vpc-resource-controller.yaml kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/vpc-admission-webhook.yaml创建 Windows Node Group:
bash# Create Windows node group using eksctl eksctl create nodegroup \ --cluster my-cluster \ --name windows-ng \ --node-type m5.large \ --nodes 2 \ --node-ami-family WindowsServer2019FullContainer验证 Windows Nodes:
bash# Verify nodes kubectl get nodes -o wide # Verify Windows node labels kubectl get nodes -l kubernetes.io/os=windows
Windows Container Deployment 示例:
# Windows Pod deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: windows-server-iis
spec:
selector:
matchLabels:
app: windows-server-iis
tier: backend
track: stable
replicas: 2
template:
metadata:
labels:
app: windows-server-iis
tier: backend
track: stable
spec:
nodeSelector:
kubernetes.io/os: windows
containers:
- name: windows-server-iis
image: mcr.microsoft.com/windows/servercore:ltsc2019
ports:
- containerPort: 80
command:
- powershell.exe
- -command
- "Add-WindowsFeature Web-Server; Invoke-WebRequest -UseBasicParsing -Uri 'https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.6/ServiceMonitor.exe' -OutFile 'C:\\ServiceMonitor.exe'; echo '<html><body><br/><br/><center><h1>Hello from Windows Container</h1></center></body></html>' > C:\\inetpub\\wwwroot\\default.html; C:\\ServiceMonitor.exe 'w3svc';"Windows Node 限制:
- Networking 限制:
- Windows nodes 不支持 HostPort 和 HostNetwork 模式。
- Windows nodes 不支持 NodeLocal DNSCache。
- Storage 限制:
- Windows nodes 仅支持某些 storage drivers。
- host path volume mounts 存在限制。
- Container Runtime:
- Windows nodes 仅支持 containerd runtime。
- Linux containers 不能在 Windows nodes 上运行。
- 功能限制:
- 某些 Kubernetes features 在 Windows nodes 上不受支持。
- privileged containers、process namespace sharing 等存在限制。
要在 EKS 中支持 Windows worker nodes,至少需要一个 Linux node group,但不强制要求两个或更多 Linux node groups。因此,“需要至少 2 个基于 Amazon Linux 的 managed node groups”不是准确的要求。
- 保护 Amazon EKS cluster 中 node groups 的 Instance Metadata Service (IMDS) 的最有效方式是什么?
- A) 禁用 IMDSv1 并要求使用 IMDSv2
- B) 使用 security group rules 限制对 169.254.169.254 的访问
- C) 对 node IAM role 设置限制性权限
- D) 将 IAM roles 附加到 pod service accounts
显示答案
答案:A) 禁用 IMDSv1 并要求使用 IMDSv2
解释: 保护 Amazon EKS cluster 中 node groups 的 Instance Metadata Service (IMDS) 的最有效方式,是禁用 IMDSv1 并要求使用 IMDSv2。IMDSv2 使用基于 session 的 requests 提供增强安全功能,可防御 Server-Side Request Forgery (SSRF) 和类似漏洞。
IMDS 安全的重要性:
Instance Metadata Service 提供有关 EC2 instances 的重要信息,包括 IAM role credentials。未经授权访问此 service 可能导致 privilege escalation 和 security breaches。在 Kubernetes environments 中,由于 pods 可以访问 node 的 IMDS,安全风险会增加。
如何配置 IMDSv2:
使用 Launch Template 配置 IMDSv2:
bash# Create launch template aws ec2 create-launch-template \ --launch-template-name eks-imdsv2-template \ --version-description "IMDSv2 required" \ --launch-template-data '{ "MetadataOptions": { "HttpTokens": "required", "HttpPutResponseHopLimit": 1, "HttpEndpoint": "enabled" } }' # Create node group using launch template eksctl create nodegroup \ --cluster my-cluster \ --name ng-imdsv2 \ --node-type m5.large \ --nodes 3 \ --launch-template-name eks-imdsv2-template \ --launch-template-version 1使用 eksctl 配置文件配置 IMDSv2:
yamlapiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster region: us-west-2 managedNodeGroups: - name: ng-imdsv2 instanceType: m5.large minSize: 2 maxSize: 5 disableIMDSv1: true metadataOptions: httpTokens: required httpPutResponseHopLimit: 1修改现有 Node Groups: 要更改现有 node groups 的 IMDS 设置,需要创建新的 node group 并迁移 workloads。现有 EC2 instances 的 IMDS 设置可以按如下方式修改:
bashaws ec2 modify-instance-metadata-options \ --instance-id i-1234567890abcdef0 \ --http-tokens required \ --http-put-response-hop-limit 1 \ --http-endpoint enabled
IMDSv2 的安全优势:
- 基于 Session 的身份验证:
- IMDSv2 使用通过 PUT requests 生成的 tokens 来验证后续 requests。
- 这些 tokens 仅在有限时间内有效。
- SSRF 攻击防护:
- 防止通过 Server-Side Request Forgery (SSRF) 漏洞访问 metadata。
- 没有 token 就无法访问 metadata。
- Hop Limit 设置:
- 设置 HTTP PUT response hop limit 可防止 metadata requests 被重定向到 instance 外部。
- 默认值为 1,确保 requests 只在 instance 内部处理。
其他 IMDS 安全措施:
完全禁用 IMDS: 如果某些 workloads 不需要 IMDS,可以完全禁用它:
yamlmetadataOptions: httpEndpoint: disabled阻止 Pod 访问 IMDS: 如果 pods 未使用 host networking,可以添加 iptables rules 阻止 IMDS 访问:
bashiptables -t nat -A PREROUTING -d 169.254.169.254/32 -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:1使用 IRSA: 使用 IAM Roles for Service Accounts (IRSA) 为 pods 提供所需 AWS 权限,并消除对 node IMDS 的依赖。
其他选项的问题:
- 使用 security group rules 限制对 169.254.169.254 的访问: Security groups 控制来自 instance 外部的 traffic,但 IMDS 从 instance 内部访问,因此无法使用 security groups 限制。
- 对 node IAM role 设置限制性权限: 这是良好的安全实践,但不会强化 IMDS 本身的安全。如果攻击者可以访问 IMDS,即使权限有限也可能被利用。
- 将 IAM roles 附加到 pod service accounts: IRSA 是确保 pods 不依赖 node IMDS 的好方法,但它不会直接强化 node IMDS 本身的安全。
禁用 IMDSv1 并要求使用 IMDSv2 是保护 EKS nodes metadata service 的最有效方式。这是 AWS 安全最佳实践,在多租户 Kubernetes environments 中尤其重要。
- 以下哪一项不是在 Amazon EKS cluster 中创建 node groups 时自定义 bootstrap scripts 的主要目的?
- A) 修改 cluster control plane components
- B) 安装额外软件
- C) 调整 kernel parameters
- D) 设置 node labels 和 taints
显示答案
答案:A) 修改 cluster control plane components
解释: 在 Amazon EKS cluster 中创建 node groups 时,自定义 bootstrap scripts 的主要目的不是修改 cluster control plane components。EKS 是 managed service,control plane 由 AWS 管理,用户无法直接修改。Bootstrap scripts 只能修改 worker node configurations。
Bootstrap Scripts 的实际使用场景:
安装额外软件:
- Monitoring agents (CloudWatch Agent, Prometheus Node Exporter 等)
- Logging tools (Fluentd, Fluent Bit 等)
- Security tools (Falco, Sysdig 等)
- Performance optimization tools
bash#!/bin/bash # Install CloudWatch agent wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm rpm -U amazon-cloudwatch-agent.rpm # Create configuration file cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << 'EOF' { "metrics": { "metrics_collected": { "mem": { "measurement": ["mem_used_percent"] }, "swap": { "measurement": ["swap_used_percent"] } } } } EOF # Start agent /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s调整 Kernel Parameters:
- Network setting optimization
- Memory management settings
- File system 和 I/O settings
bash#!/bin/bash # Adjust kernel parameters cat > /etc/sysctl.d/99-kubernetes.conf << EOF net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_max_syn_backlog = 40000 net.core.somaxconn = 40000 net.core.netdev_max_backlog = 40000 vm.max_map_count = 262144 EOF # Apply changes sysctl --system设置 Node Labels 和 Taints:
- 设置 node role labels
- 设置 hardware characteristic labels
- 为特定 workloads 设置 taints
bash#!/bin/bash # Execute EKS bootstrap script /etc/eks/bootstrap.sh my-cluster \ --kubelet-extra-args '--node-labels=node.kubernetes.io/role=worker,environment=prod,node-type=compute --register-with-taints=dedicated=compute:NoSchedule'Disk 和 File System 配置:
- 挂载额外 volumes
- File system optimization
- Temporary storage configuration
bash#!/bin/bash # Format and mount additional EBS volume mkfs -t xfs /dev/nvme1n1 mkdir -p /data mount /dev/nvme1n1 /data echo "/dev/nvme1n1 /data xfs defaults 0 0" >> /etc/fstab安全配置:
- 设置 firewall rules
- Security hardening settings
- Log audit configuration
bash#!/bin/bash # Set firewall rules iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j DROP # Security hardening settings sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config systemctl restart sshd
如何实现 Bootstrap Scripts:
使用 Launch Template 的 User Data Script:
bash# Create launch template aws ec2 create-launch-template \ --launch-template-name eks-custom-bootstrap \ --version-description "Custom bootstrap script" \ --launch-template-data '{ "UserData": "BASE64_ENCODED_USER_DATA_SCRIPT" }' # Create node group using launch template eksctl create nodegroup \ --cluster my-cluster \ --name custom-ng \ --node-type m5.large \ --nodes 3 \ --launch-template-name eks-custom-bootstrap \ --launch-template-version 1使用 eksctl 配置文件的 User Data Script:
yamlapiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster region: us-west-2 managedNodeGroups: - name: custom-ng instanceType: m5.large minSize: 2 maxSize: 5 preBootstrapCommands: - "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/99-kubernetes.conf" - "sysctl --system" kubeletExtraArgs: node-labels: "environment=prod,node-type=compute"
Cluster Control Plane Components:
EKS cluster 的 control plane components 由 AWS 管理,不能通过 bootstrap scripts 修改:
- API Server
- Controller Manager
- Scheduler
- etcd
- CoreDNS
要修改这些 components,必须通过 AWS 提供的 APIs 在 cluster 级别进行配置。例如,control plane logging 可以按如下方式配置:
aws eks update-cluster-config \
--name my-cluster \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'Bootstrap script 只能修改 worker node configurations,不能修改 cluster control plane components。因此,“修改 cluster control plane components”不是 bootstrap script 的主要目的。