Prepartion

  1. 如果使用了Cilium作为CNI插件,则需要修改关闭一些Cilium的特性。
1
kubectl edit cm/cilium-config -n kube-system

增加以下内容

1
2
bpf-lb-sock-hostns-only: "true"
cni.exclusive: "false"
  1. 获取binary
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Get binary
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install-edge | sh

# Add PATH
export PATH=$HOME/.linkerd2/bin:$PATH

# Verify Install
linkerd version

# Vaildate K8S Cluster 
linkerd check --pre

Step by Step install

  • 创建命名空间
1
kubectl create namespace linkerd
  • 安装Cert-Manager
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
## 方法一 Helm方法
helm repo add jetstack https://charts.jetstack.io --force-update

helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

kubectl rollout status -n cert-manager deploy

## 方法二 更适合中国宝宝体质
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.0/cert-manager.yaml
  • 安装Trust-Manager
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
## 方法一: Helm方法
helm install \
  trust-manager jetstack/trust-manager \
  --namespace cert-manager \
  --set app.trust.namespace=cert-manager \
  --wait

# 方法二: 离线方法
# 从GitHub源码库下载Release后解压,进入deploy目录,修改values.yaml,将tag修改成当前下载的版本,前面加一个v,不然应用helm install时会提示无镜像
tag: v0.16.0

# 使用本地的Charts
cd trust-manager-0.16.0/deploy/charts/trust-manager
helm install \
  trust-manager ./ \
  --namespace cert-manager \
  --set app.trust.namespace=cert-manager \
  --wait
  • 更新RBAC
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cert-manager
  namespace: linkerd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cert-manager-secret-creator
  namespace: linkerd
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["create", "get", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cert-manager-secret-creator-binding
  namespace: linkerd
subjects:
  - kind: ServiceAccount
    name: cert-manager
    namespace: linkerd
roleRef:
  kind: Role
  name: cert-manager-secret-creator
  apiGroup: rbac.authorization.k8s.io
EOF
  • 创建Issuer
1
2
3
4
5
6
7
8
9
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: linkerd-trust-root-issuer
  namespace: cert-manager
spec:
  selfSigned: {}
EOF
  • 创建Trust Anchor并设置成ClusterIssuer

    ClusterIssuer: 可以跨命名空间引用

    Issuer 只能在当前命名空间生效

根证书有效期为1年,离失效2个月前,开始自动轮转证书

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
kubectl apply -f - <<EOF
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: linkerd-trust-anchor
  namespace: cert-manager
spec:
  issuerRef:
    kind: Issuer
    name: linkerd-trust-root-issuer
  secretName: linkerd-trust-anchor
  isCA: true
  commonName: root.linkerd.cluster.local
  duration: 8760h0m0s  # 1 year
  renewBefore: 7320h0m0s # 8 months
  privateKey:
    rotationPolicy: Always
    algorithm: ECDSA
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: linkerd-identity-issuer
  namespace: cert-manager
spec:
  ca:
    secretName: linkerd-trust-anchor
EOF
  • 创建Linkerdidentity issuer

使用linkerd-identity-issuer创建工作负载的身份颁发者证书,该证书后续用于给工作负载颁发证书。工作负载的证书每48小时后失效。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
kubectl apply -f - <<EOF
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: linkerd-identity-issuer
  namespace: linkerd
spec:
  issuerRef:
    name: linkerd-identity-issuer
    kind: ClusterIssuer
  secretName: linkerd-identity-issuer
  isCA: true
  commonName: identity.linkerd.cluster.local
  duration: 48h0m0s
  renewBefore: 25h0m0s
  privateKey:
    rotationPolicy: Always
    algorithm: ECDSA
EOF
  • 通过linkerd-trust-anchor创建一个linkerd-previous-anchor

这是因为在证书轮转时,新老证书都需要被Linkerd信任。

1
2
3
4
kubectl get secret -n cert-manager linkerd-trust-anchor -o yaml \
        | sed -e s/linkerd-trust-anchor/linkerd-previous-anchor/ \
        | egrep -v '^  *(resourceVersion|uid)' \
        | kubectl apply -f -
  • 创建Boudle资源

将新与旧的根证书都加入信任包中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
kubectl apply -f - <<EOF
---
apiVersion: trust.cert-manager.io/v1alpha1
kind: Bundle
metadata:
  name: linkerd-identity-trust-roots
  namespace: linkerd
spec:
  sources:
    - secret:
        name: "linkerd-trust-anchor"
        key: "tls.crt"
    - secret:
        name: "linkerd-previous-anchor"
        key: "tls.crt"
  target:
    configMap:
      key: "ca-bundle.crt"
    namespaceSelector:
      matchLabels:
        linkerd.io/is-control-plane: "true"
EOF
  • 安装Linkerd
1
2
3
4
5
6
7
8
linkerd install --crds | kubectl apply -f -

kubectl label namespace linkerd linkerd.io/is-control-plane=true

linkerd install  --ha \
  --set identity.externalCA=true \
  --set identity.issuer.scheme=kubernetes.io/tls \
  | kubectl apply -f -
  • 验证安装
1
linkerd check

安装Linkerd Viz(可选)

1
linkerd viz install | kubectl apply -f -

因为默认Linkerd强制做了域名校验。所以要想通过NodePort的方式直接访问,需要做两步

  • Service webClusterIP修改为NodePort
  • Deployment web修改启动参数,-enforced-host=.*

注入Linkerd代理

1
cat deployment.yml | linkerd inject - | kubectl apply -f -