介绍
本章节我们演示如何暴露服务给外部终端用户访问。
准备和验证
1.准备配置文件
mkdir -p ~/environment/expose && cd ~/environment/expose
cat <<eof> run-my-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
namespace: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EoF
2.部署和查看
部署组件
cd ~/environment/expose
kubectl create ns my-nginx
kubectl -n my-nginx apply -f run-my-nginx.yaml
kubectl -n my-nginx get pods -o wide
kubectl -n my-nginx get pods -o yaml | grep 'podIP:'
获得两个Pod的IP,如下
podIP: 172.31.36.83
podIP: 172.31.4.94
发布服务
发布服务
kubectl -n my-nginx expose deployment/my-nginx
kubectl -n my-nginx get svc my-nginx
kubectl -n my-nginx describe svc my-nginx
启动一个 Pod 做个内网测试,访问上面 describe 出来的集群服务 IP 地址
export MyClusterIP=$(kubectl -n my-nginx get svc my-nginx -ojsonpath='{.spec.clusterIP}')
echo ${MyClusterIP}
kubectl -n my-nginx run -i --tty load-generator --generator=run-pod/v1 --rm --env="MyClusterIP=${MyClusterIP}" --image=busybox /bin/sh
获取请求返回的信息
wget -q -O - ${MyClusterIP} | grep '<title>'
如果输出内容为如下所示,退出这个新的pod即可
<title>Welcome to nginx!</title>
访问服务
K8s 支持两种主要的服务发现
- 环境变量
- DNS(基于 CoreDNS 实现)
1.环境变量
举个例子说我们可以看到 pod 的名字(这就是一个典型的环境变量)
kubectl -n my-nginx get pods -l run=my-nginx -o wide
或者查看对应的环境变量
export mypod=$(kubectl -n my-nginx get pods -l run=my-nginx -o jsonpath='{.items[0].metadata.name}')
kubectl -n my-nginx exec ${mypod} -- printenv | grep HOSTNAME
如果我们重置一下,发现环境变量也进行的变化
kubectl -n my-nginx rollout restart deployment my-nginx
kubectl -n my-nginx get pods -l run=my-nginx -o wide
export mypod=$(kubectl -n my-nginx get pods -l run=my-nginx -o jsonpath='{.items[0].metadata.name}')
kubectl -n my-nginx exec ${mypod} -- printenv | grep HOSTNAME
2.DNS
通过如下命令查询 CoreDNS 服务的运行情况
kubectl get service -n kube-system -l k8s-app=kube-dns
我们另外启动一个 pod,来测试一下
kubectl -n my-nginx run curl --generator=run-pod/v1 --rm --image=radial/busyboxplus:curl -i --tty
登录后执行
nslookup my-nginx
返回类似如下表示工作正常
Server: 10.100.0.10
Address 1: 10.100.0.10 kube-dns.kube-system.svc.cluster.local
Name: my-nginx
Address 1: 10.100.247.157 my-nginx.my-nginx.svc.cluster.local
暴露服务
K8s 支持两种主要的服务发现
- NodePort 方式
- LoadBalancer 方式
当前暴露的服务是 ClusterIP,并不是 ELB
kubectl -n my-nginx get svc my-nginx
返回如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.100.247.157 <none> 80/TCP 24m
我们把他修改成支持 LoadBalancer 的方式
kubectl -n my-nginx patch svc my-nginx -p '{"spec": {"type": "LoadBalancer"}}'
kubectl -n my-nginx get svc my-nginx
返回如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx LoadBalancer 10.100.247.157 ad59722ca27a940ca9a4b1ea5040425f-840867124.eu-west-1.elb.amazonaws.com 80:30247/TCP 25m
测试一下请求
export loadbalancer=$(kubectl -n my-nginx get svc my-nginx -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
curl -k -s http://${loadbalancer} | grep title
如果 ELB 长时间没有响应,可以用如下方式查询状态
kubectl -n my-nginx describe service my-nginx | grep Ingress
Ingress
Ingress 是控制前端路由进来到服务的组件。
在 EKS 里面,默认的 AWS ALB Ingress Controller 是 AWS 的 Load Balancer Controller, 更多细节见这里
针对不同的服务类型,选用不同的组件
- Ingress: 使用 ALB(Application Load Balancers)
- Service: 使用 NLB(Network Load Balancers)
此处我们使用 helm 来安装和配置 ALB Controller。
1.配置 IAM 角色
确定您的集群是否有现有的 IAM OIDC 提供商。
aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text
下载 IAM Load Balancer Controller 的 AWS 策略
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
创建 IAM 策略
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
创建 IAM 角色和 ServiceAccount
eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-policy-arn arn:aws:iam::921283538843:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--approve
创建 TargetGroupBinding CRDS
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
kubectl get crd
2.部署 ALB Controller
通过 helm 来部署 ALB Controller
helm repo add eks https://aws.github.io/eks-charts
helm upgrade -i aws-load-balancer-controller \
eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
-n kube-system
kubectl get deployment -n kube-system aws-load-balancer-controller
需要子网进行标记,便 Kubernetes 知道仅将这些子网用于外部负载均衡器,然后才可以正常使用。
aws ec2 create-tags --resources subnet-958223cf --tags Key=kubernetes.io/role/elb,Value=1
aws ec2 create-tags --resources subnet-b7caaed1 --tags Key=kubernetes.io/role/elb,Value=1
aws ec2 create-tags --resources subnet-b3b7c0fb --tags Key=kubernetes.io/role/elb,Value=1
3.部署样例应用
通过如下方式部署2048样例程序
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/examples/2048/2048_full.yaml
几分钟后,验证是否已使用以下命令创建入口资源。
kubectl get ingress/ingress-2048 -n game-2048
输出:
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-2048 <none> * k8s-game2048-ingress2-184c5765e8-1545216127.eu-west-1.elb.amazonaws.com 80 17h
打开浏览器并从上一命令输出导航到 ADDRESS
URL 以查看示例应用程序。如果您没有看到任何内容,请等待几分钟并刷新浏览器。
4.清理环境
当你不需要此服务的时候,可以通过如下方式删除此环境
cd ~/environment/expose/
kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/examples/2048/2048_full.yaml
helm uninstall aws-load-balancer-controller -n kube-system
kubectl delete -k github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master
eksctl delete iamserviceaccount \
--cluster my-cluster \
--name aws-load-balancer-controller \
--namespace kube-system \
--wait
aws iam delete-policy \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy