Deploy a deploy

来自linuxsa wiki
跳转到导航 跳转到搜索

flow

Browser
  │
  │ DNS lookup: k8s-default-helloapp-47ccac942d-1337560140.ap-east-1.elb.amazonaws.com
  ▼
AWS Public DNS → resolves to ALB's public IP
  │
  ▼
AWS ALB (k8s-default-helloapp-47ccac942d)
  │  Listener: HTTP:80
  │
  │ Rule matching — Priority 1: path-pattern /*
  ▼
Target Group (k8s-default-helloapp-f07e0f7fc3)
  │
  ├─→ 10.0.11.28:80   (healthy) ┐
  │                              ├ round-robin, pick one
  └─→ 10.0.11.117:80  (healthy) ┘
  │
  ▼
nginxdemos/hello Pod → HTTP response


apps dig dig k8s-default-helloapp-47ccac942d-1337560140.ap-east-1.elb.amazonaws.com

k8s-default-helloapp-47ccac942d-1337560140.ap-east-1.elb.amazonaws.com.	60 IN A	95.40.233.44
k8s-default-helloapp-47ccac942d-1337560140.ap-east-1.elb.amazonaws.com.	60 IN A	95.40.232.238


EIP  95.40.233.44    A	95.40.232.238

enha alb-ingress

可选:IngressGroup(多服务共享同一个 ALB)

如果多个服务都用独立 Ingress,每个都会创建一个新 ALB,成本较高。可以用 IngressGroup 共享:

yamlmetadata:
  annotations:
    alb.ingress.kubernetes.io/group.name: my-shared-alb   # 同一个 group 的 Ingress 共享一个 ALB
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip


*********
**IngressGroup是什么**

默认情况下每个Ingress资源都会创建一个独立的ALB,成本较高。IngressGroup让多个Ingress共享同一个ALB,通过不同的path或host来区分流量。

---

**场景:两个服务共享一个ALB**

```
                    ALB (共享,只有一个)
                         │
              ┌──────────┴──────────┐
              │                     │
         /api/*                  /web/*
              │                     │
         api-service            web-service
         (api的Pod)             (web的Pod)
```

---

**Deployment和Service(两个服务各自独立)**

```yaml
# api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api-app
  template:
    metadata:
      labels:
        app: api-app
    spec:
      containers:
      - name: api-app
        image: nginxdemos/hello
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: api-svc
spec:
  selector:
    app: api-app
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
```

```yaml
# web-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: nginxdemos/hello
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
```

---

**关键:两个Ingress加上同一个group.name**

```yaml
# api-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/group.name: my-shared-alb   # ← 关键,两个Ingress写同一个值
    alb.ingress.kubernetes.io/group.order: "10"           # ← 规则优先级,数字越小越优先
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port:
              number: 80
```

```yaml
# web-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/group.name: my-shared-alb   # ← 和上面一样
    alb.ingress.kubernetes.io/group.order: "20"
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-svc
            port:
              number: 80
```

---

**Apply并验证**

```bash
kubectl apply -f api-deployment.yaml
kubectl apply -f web-deployment.yaml
kubectl apply -f api-ingress.yaml
kubectl apply -f web-ingress.yaml

# 两个Ingress会共享同一个ALB地址
kubectl get ingress
```

输出应该是:
```
NAME          CLASS   HOSTS   ADDRESS                              PORTS   AGE
api-ingress   alb     *       k8s-shared-mysharedalb-xxx.elb...   80      1m
web-ingress   alb     *       k8s-shared-mysharedalb-xxx.elb...   80      1m
```

**两个Ingress的ADDRESS完全一样**,说明共享同一个ALB。

---

**验证路由**

```bash
ALB=<ADDRESS>

# 打api路径
curl http://$ALB/api

# 打web路径  
curl http://$ALB/web
```

---

**也可以按host区分(更常见的生产用法)**

```yaml
# api-ingress.yaml
spec:
  ingressClassName: alb
  rules:
  - host: api.company.com      # ← 按域名区分
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port:
              number: 80
```

```yaml
# web-ingress.yaml
spec:
  ingressClassName: alb
  rules:
  - host: web.company.com      # ← 不同域名,同一个ALB
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-svc
            port:
              number: 80
```

---

**对比:有无IngressGroup的成本差异**

```
没有IngressGroup:                有IngressGroup:

api-ingress → ALB-1              api-ingress ─┐
web-ingress → ALB-2              web-ingress  ├→ ALB-1 (共享)
foo-ingress → ALB-3              foo-ingress ─┘

3个ALB × $0.008/hr               1个ALB × $0.008/hr
= $0.024/hr                      = $0.008/hr
= ~$17/月                        = ~$6/月
```

服务越多,节省越明显。生产环境通常按团队或业务线划分group,比如 `group.name: team-a` 、`group.name: team-b`,每个team共享一个ALB。


************
https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html

是同一个东西,官方文档和我给你讲的是完全一致的概念。对比一下几个关键点:

**IngressGroup部分完全一致:**

官方文档:
```yaml
alb.ingress.kubernetes.io/group.name: my-group
alb.ingress.kubernetes.io/group.order: '10'
```

我给你的示例:
```yaml
alb.ingress.kubernetes.io/group.name: my-shared-alb
alb.ingress.kubernetes.io/group.order: "10"
```

一模一样。

**有几点官方文档补充的细节值得注意:**

**1. group.name的命名规则有限制:**
- 不超过63个字符
- 只能包含小写字母、数字、`-`、`.`
- 必须以字母或数字开头和结尾

**2. 官方推荐ALB Controller版本 `2.7.2` 或更高**,你装的是 `v3.4.1`,比推荐版本新,没问题。

**3. 子网Tag这里官方有个重要说明:**

如果使用 `2.1.2` 或更高版本,子网Tag是可选的,但如果同一VPC里有多个集群,或者多个AWS服务共享子网,强烈建议还是打上Tag。ALB Controller不会检查路由表来判断子网是public还是private,它依赖Tag来做自动发现。

**4. 官方有个安全警告值得注意:**

只有当所有有权限创建或修改Ingress资源的Kubernetes用户都在同一个信任边界内时,才应该使用IngressGroup。否则其他用户可能把自己的Ingress加入同一个group,用更高优先级的规则覆盖已有规则,造成安全风险。

所以生产环境里一般按团队或业务线划分group,不要让所有服务共用同一个group name。

have an eks cluster and install dashboard

EKS Fundamentals

install alb

install eksctl

https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz


aws eks update-kubeconfig --region <your region> --name <clustername>
kubectl get nodes



AWS Load Balancer Controller

kubectl get deployment -n kube-system aws-load-balancer-controller
if return Error from server (NotFound)

# 1. 创建IAM policy(如果还没创建过)
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.13.0/docs/install/iam_policy.json

aws iam create-policy \
  --policy-name AWSLoadBalancerControllerIAMPolicy \
  --policy-document file://iam_policy.json

# 2. 创建IAM Service Account(需要先启用OIDC provider,如果没启用先跑这行)
#eksctl utils associate-iam-oidc-provider --cluster=<集群名> --approve
eksctl utils associate-iam-oidc-provider --region=ap-east-1 --cluster=my-eks --approve

eksctl create iamserviceaccount \
  --cluster=<集群名> \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --attach-policy-arn=arn:aws:iam::<你的account-id>:policy/AWSLoadBalancerControllerIAMPolicy \
  --override-existing-serviceaccounts \
  --approve

# 3. Helm安装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=<集群名> \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller

kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl get pods -n kube-system | grep aws-load-balancer
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
aws-load-balancer-controller   2/2     2            2           84s
aws-load-balancer-controller-644668f56c-7nnkh   1/1     Running   0          84s
aws-load-balancer-controller-644668f56c-qzhdl   1/1     Running   0          84s
➜  claude ls


ng demo


ALB Controller装好了,2个pod都Running。现在可以部署应用了。

**1. 创建Deployment**

```bash
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: nginxdemos/hello
        ports:
        - containerPort: 80
EOF

kubectl apply -f deployment.yaml
```

**2. 创建Service**

```bash
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-app-svc
spec:
  selector:
    app: hello-app
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
EOF

kubectl apply -f service.yaml
```

**3. 创建Ingress(走ALB)**

```bash
cat <<EOF > ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-app-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello-app-svc
            port:
              number: 80
EOF

kubectl apply -f ingress.yaml
```

**4. 检查pod状态**

```bash
kubectl get pods -w
```

等pod都Running后,Ctrl+C退出,然后检查Ingress的ALB地址:

```bash
kubectl get ingress hello-app-ingress
```

ADDRESS字段出现域名(通常要等1-2分钟)后,浏览器访问那个地址就能看到nginx的hello页面了。

有个小提醒:用ALB internet-facing需要确认你的public子网有打上 `kubernetes.io/role/elb` 标签,且Ingress Controller的IAM权限里要能访问对应的子网,不然ALB可能创建失败或者一直显示无ADDRESS。如果卡住了告诉我,我们一起排查。

result

文件:Alb-2d.png