一些用户可能有端到端加密的监管要求,在本节,我们将在EKS上设置端到端加密,流量源自客户端,并终止于Pod应用
AWS Load Balancer Controller
支持创建出NLB,使用IP模式,这样可以直接将流量路由到Pod内部,以减少走worker节点网络的延迟:
首先,创建可供 AWS Load Balancer Controller使用的 IAM 策略:
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.1/docs/install/iam_policy.json
创建policy:
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
将<ACCOUNT_ID>
替换为实际账户 ID,将<cluster-name>
替换为实际的集群名称,然后运行以下命令创建service account:
eksctl create iamserviceaccount \
--cluster=<cluster-name> \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name "AmazonEKSLoadBalancerControllerRole" \
--attach-policy-arn=arn:aws:iam::<ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
使用Helm安装Load Balancer Controller
:
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=<cluster-name> \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
使用以下命令验证Load Balancer Controller是否正在运行:
kubectl get deployment -n kube-system aws-load-balancer-controller
这可能需要几分钟才能完成。重复上一个命令以检查状态, 直到看到aws-load-balancer-controller
已准备就绪,状态为Ready 2/2
现在将应用到部署到EKS,它是一个简单的 NGINX Web 服务器,返回 Hello pod-hostname
复制以下 YAML,保存为nlb-tls-app.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nlb-tls-app
spec:
replicas: 1
selector:
matchLabels:
app: nlb-tls-app
template:
metadata:
labels:
app: nlb-tls-app
spec:
containers:
- name: nlb-tls-app
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8443
volumeMounts:
- name: secret
mountPath: /etc/nginx/ssl
readOnly: true
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: secret
secret:
secretName: nlb-tls-app-secret
- name: config-volume
configMap:
name: secure-config
---
apiVersion: v1
kind: Service
metadata:
name: nlb-tls-app
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip"
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
ports:
- port: 443
targetPort: 8443
protocol: TCP
name: https
selector:
app: nlb-tls-app
type: LoadBalancer
---
apiVersion: v1
kind: ConfigMap
metadata:
name: secure-config
data:
app.conf: |-
server {
listen 8443 ssl proxy_protocol;
real_ip_header proxy_protocol;
set_real_ip_from 192.168.0.0/16;
server_name <your_server_name>;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
default_type text/plain;
location / {
return 200 "hello from pod $hostname\n";
}
}
Service
对象中,共有三个注解:
proxy protocol v2
,以将客户端源 IP 地址传递到 podConfigMap
对象包含 NGINX 服务器的配置:
server_name
指令中添加NLB的 DNS ,但我们还没有这个- NLB将在我们apply yaml 时创建, 我们稍后会对此ConfigMap
进行编辑。应用该yaml:
kubectl apply -f nlb-tls-app.yaml
在EC2控制台会看到一个新的负载均衡器,其 DNS 名称包括nlbtlsap
如下所示:
注意:配置NLB可能需要几分钟的时间。
NLB设置完毕后,我们可以编辑ConfigMap
以添加新的负载均衡器地址作为server_name
值, 使用命令kubectl edit configmap secure-config
编辑app.conf
,ConfigMap
如下所示,将该server_name
字段替换为NLB DNS 名称:
运行以下命令来验证应用程序是否已启动并正在运行:
kubectl get pods
Pod 尚未显示为“Running” - 这是因为我们需要为新的NLB请求证书
使用 AWS Private CA 颁发私有证书。
创建一个名为nlb-lab-tls.yaml
的文件并将以下内容保存在其中:
kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
name: nlb-lab-tls-cert
spec:
commonName: e2e-eks-example
dnsNames:
- k8s-default-nlbtlsap-5583fd0a04-3d8832058330c9f6.elb.us-west-2.amazonaws.com # 替换为实际的NLB DNS
duration: 2160h0m0s
issuerRef:
group: awspca.cert-manager.io
kind: AWSPCAClusterIssuer
name: demo-test-root-ca
renewBefore: 360h0m0s
secretName: nlb-tls-app-secret
usages:
- server auth
- client auth
privateKey:
algorithm: "RSA"
size: 2048
创建资源并请求证书:
kubectl apply -f nlb-lab-tls.yaml
运行以下命令验证证书是否正确颁发:
kubectl get certificate
状态显示Ready:
现在这个新证书已准备就绪,检查之前pod的状态:
kubectl get deployments -A
应该看到显示1/1 Ready
(有可能需要几分钟才能完成):
访问nlb:
https://k8s-default-nlbtlsap-5583fd0a04-3d8832058330c9f6.elb.us-west-2.amazonaws.com
返回hello from pod...
,在浏览器地址栏中有一个“锁”,表明连接是安全的。单击锁的图标,查看证书:
接下来,验证客户端源 IP 地址是否已保留:
kubectl logs nlb-tls-app-547b78746-skmns # 替换为实际pod的名称
输出示例:
Pod 日志中请求的原始 IP与本机的公共 IP 匹配,该连接源自使用浏览器, 并在单个 Pod 上终止
前面实验中,已经将Root CA在本机上信任,所以在浏览器中可以正常访问。