在本实验中,我们将使用 AWS Certificate Manager Private Certificate Authority (ACM PCA) 颁发的私有证书,在 App Mesh 的两个应用之间启用 TLS 加密。
要为 appmesh-controller创建IRSA(IAM Roles for Service Account),请按照 此处
来创建;或者按照https://github.com/aws/aws-app-mesh-examples/blob/main/walkthroughs/eks
的流程。如果将所有 IAM 权限已经添加到 IAM role,则节点应具有以下 IAM 权限:AWSAppMeshFullAccess
、AWSCloudMapFullAccess
。
将 ACM PCA 用于 TLS 时需要一些额外的 IAM 权限。请验证worker节点的 IAM 角色是否具有以下 IAM 权限:
appmesh:StreamAggregatedResources
acm:ExportCertificate
acm-pca:GetCertificateAuthorityCertificate
aws-app-mesh-controller-for-k8s 版本大于等于v1.0.0 。运行以下命令以检查您正在运行的appmesh-controller版本:
$ kubectl get deployment -n appmesh-system appmesh-controller -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'|tail -n1
克隆仓库并进入到 walkthrough/howto-k8s-tls-acm
文件夹,所有命令都将从这个位置执行:
git clone https://github.com/aws/aws-app-mesh-examples
cd walkthroughs/howto-k8s-tls-acm
设置环境变量
export AWS_ACCOUNT_ID=<your_account_id>
export AWS_DEFAULT_REGION=us-west-2
export SERVICES_DOMAIN="howto-k8s-tls-acm.svc.cluster.local" # 创建 AWS Certificate Manager PCA时要使用的SERVICES_DOMAIN
在我们加密Mesh中服务之间的流量之前,我们需要生成一个证书。 App Mesh 当前支持由 ACM 私有证书颁发机构 颁发的证书,我们将在此步骤中创建它。
首先在 ACM 中创建根证书颁发机构 (CA):
注意:您需要为每个 ACM PCA按月支付费用。 有关更多信息,请参阅 AWS Certificate Manager 定价 .
export ROOT_CA_ARN=`aws acm-pca create-certificate-authority \
--certificate-authority-type ROOT \
--certificate-authority-configuration \
"KeyAlgorithm=RSA_2048,
SigningAlgorithm=SHA256WITHRSA,
Subject={
Country=US,
State=WA,
Locality=Seattle,
Organization=App Mesh Examples,
OrganizationalUnit=TLS Example,
CommonName=${SERVICES_DOMAIN}}" \
--query CertificateAuthorityArn --output text`
接下来,您需要对根 CA 进行自签名(self-sign)。 首先检查 CSR 内容:
ROOT_CA_CSR=`aws acm-pca get-certificate-authority-csr \
--certificate-authority-arn ${ROOT_CA_ARN} \
--query Csr --output text`
使用自身作为发行人签署 CSR。
请注意,如果您使用的是 AWS CLI 2的版本,则需要在调用issue-certificate
命令之前通过base64编码传递 CSR 数据。
注意,这一步使用aws cli2版本测试时,发现报错,此时可以重新安装v1版本来进行后面的操作:
sudo pip3 install awscli
AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1)
[[ ${AWS_CLI_VERSION} -gt 1 ]] && ROOT_CA_CSR="$(echo ${ROOT_CA_CSR} | base64)"
ROOT_CA_CERT_ARN=`aws acm-pca issue-certificate \
--certificate-authority-arn ${ROOT_CA_ARN} \
--template-arn arn:aws:acm-pca:::template/RootCACertificate/V1 \
--signing-algorithm SHA256WITHRSA \
--validity Value=10,Type=YEARS \
--csr "${ROOT_CA_CSR}" \
--query CertificateArn --output text`
然后将签名证书导入,作为根 CA:
ROOT_CA_CERT=`aws acm-pca get-certificate \
--certificate-arn ${ROOT_CA_CERT_ARN} \
--certificate-authority-arn ${ROOT_CA_ARN} \
--query Certificate --output text`
再次注意 AWS CLI 版本 2,您需要通过编码传递证书数据:
[[ ${AWS_CLI_VERSION} -gt 1 ]] && ROOT_CA_CERT="$(echo ${ROOT_CA_CERT} | base64)"
导入证书:
aws acm-pca import-certificate-authority-certificate \ --certificate-authority-arn $ROOT_CA_ARN \ --certificate "${ROOT_CA_CERT}"
我们还希望授予 CA 自动续期托管证书的权限:
aws acm-pca create-permission \ --certificate-authority-arn $ROOT_CA_ARN \ --actions IssueCertificate GetCertificate ListPermissions \ --principal acm.amazonaws.com
使用此 CA 从 ACM 请求托管证书:
export CERTIFICATE_ARN=`aws acm request-certificate \ --domain-name "*.${SERVICES_DOMAIN}" \ --certificate-authority-arn ${ROOT_CA_ARN} \ --query CertificateArn --output text`
对于托管证书,ACM 将自动续订即将到期的证书,而 App Mesh 将自动分发续订的证书。
我们将设置一个具有四个virtual nodes的mesh:Frontend、Blue、Green和Red,一个virtual service:color, 一个virtual router:color。
先创建mesh:
./mesh.sh up
Frontend有对应的virtual service
(color)后端,virtual service
(color)使用virtual router
(color)。 Virtual router
(color)配置了三个路由:
blue
green
red
virtual node blue
配置了为其侦听器启用了 TLS。 这是blue
virtual node的定义:
apiVersion: appmesh.k8s.aws/v1beta2kind: VirtualNodemetadata: name: blue namespace: howto-k8s-tls-acmspec: podSelector: matchLabels: app: color version: blue listeners: - portMapping: port: 8080 protocol: http healthCheck: protocol: http path: '/ping' healthyThreshold: 2 unhealthyThreshold: 2 timeoutMillis: 2000 intervalMillis: 5000 tls: mode: STRICT certificate: acm: certificateARN: arn:aws:acm:us-west-2:<ACCOUNT_ID>:certificate/<certificate> serviceDiscovery: dns: hostname: color-blue.howto-k8s-tls-acm.svc.cluster.local
tls
模块指定了要使用的 ACM 证书。
kubectl run -i --tty curler --image=public.ecr.aws/k8m1l3p1/alpine/curler:latest --rmcurl -H "color_header: blue" front.howto-k8s-tls-acm.svc.cluster.local:8080/; echo;
当使用 HTTP 标头color_header: blue
时,会看到响应成功:
让我们检查 SSL 握手的统计信息:
BLUE_POD=$(kubectl get pod -l "version=blue" -n howto-k8s-tls-acm --output=jsonpath={.items..metadata.name})kubectl exec -it $BLUE_POD -n howto-k8s-tls-acm -c envoy -- curl -s http://localhost:9901/stats | grep ssl.handshake
您应该会看到类似于以下内容的输出:listener.0.0.0.0_15000.ssl.handshake:1
,表明在前端和blue color app
之间成功进行 SSL 握手。
如果您想保持应用程序运行,可以忽略这一节的操作。
运行以下命令以清理我们创建的资源。:
kubectl delete -f _output/manifest.yaml
删除 ECR 仓库, force
标志将删除 ECR 存储库中的 docker 镜像:
aws ecr delete-repository --repository-name howto-k8s-tls-acm/colorapp --forceaws ecr delete-repository --repository-name howto-k8s-tls-acm/feapp --force
删除证书:
aws acm delete-certificate --certificate-arn $CERTIFICATE_ARNaws acm-pca update-certificate-authority --certificate-authority-arn $ROOT_CA_ARN --status DISABLEDaws acm-pca delete-certificate-authority --certificate-authority-arn $ROOT_CA_ARN
删除 appmesh-controller
deployment:
helm delete appmesh-controller -n appmesh-system
删除 appmesh-system
命名空间:
kubectl delete ns appmesh-system