Linkerd 1.7 linkerd-inject error

Following the doc, https://linkerd.io/features/transparent-proxying/ ,i enable linkerd-inject.

Question 1:

kubectl apply -f <(linkerd-inject -f <your k8s config>.yml -linkerdPort 4140)

what’s the .yml ? linkerd-service-mesh.yml or my application.yml?

Question 2:
Whether

kubectl apply -f  <(linkerd-servicemesh.yml -linkerdPort 4140)

or

kubectl apply -f  <(lmyapplicaiton.yml -linkerdPort 4140)

not work.

curl -H ‘servicename.servicenamespace’ http://external-ip:4140,response error:

Exceeded 10.seconds binding timeout while resolving name: /svc/servicename.servicenamespace

Question 3:

use manual,i modify my yaml file,add init-container to spec for deployment.then ‘kubectl apply -f myapplication.yaml’,but the init-container stauts always 'Init:CrashLoopBackOff’.

the full log ’ Error from server (BadRequest): container “my container” in pod “mycontainer-v1-67b886bfcd-f9ffk” is waiting to start: PodInitializing’.

Hi @supermario!

I’m curious to know if you’ve considered using Linkerd 2, instead of Linkerd 1. Linkerd 2 is designed to be used with Kubernetes, and it is much easier to get started.

Regarding your questions about Linkerd 1:

Question 1:

  • The .yml is the file that defines your resource. It could be a Deployment, DaemonSet, or other Kubernetes resource that creates a ReplicationSet

Question 2:
We’ll need to get more info about this. Can you share the config for the Linkerd DaemonSet? It will look like this example.

Question 3:
Can you share the entire yaml file that you added the initContainer spec?

Charles

@cpretzer Thank you for your reply.

I first tried to use linkerd 2.x version, and use nginx ingress controller,but encountered some problems.

I use jemeter for concurrent testing. When I reach 1000 / s connection, I get a lot of 503 errors. But the
linkerd dashboard shows 100% success rate.

github has related issues, https://github.com/linkerd/linkerd2/issues/4316.

Therefore, re-select the 1.x version.

Question 1:
I mean, is this yml file the file that I installed linkerd to kubernetes, or the file that I deployed the program to kubernetes myself?

Question 2:
I manually added the initcontainer content to the linkerd installation yml file.

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: l5d-config
  namespace: linkerd
data:
  config.yaml: |-
    admin:
      ip: 0.0.0.0
      port: 9990

    # Namers provide Linkerd with service discovery information.  To use a
    # namer, you reference it in the dtab by its prefix.  We define 4 namers:
    # * /io.l5d.k8s gets the address of the target app
    # * /io.l5d.k8s.http gets the address of the http-incoming Linkerd router on the target app's node
    # * /io.l5d.k8s.h2 gets the address of the h2-incoming Linkerd router on the target app's node
    # * /io.l5d.k8s.grpc gets the address of the grpc-incoming Linkerd router on the target app's node
    namers:
    - kind: io.l5d.k8s
    - kind: io.l5d.k8s
      prefix: /io.l5d.k8s.http
      transformers:
        # The daemonset transformer replaces the address of the target app with
        # the address of the http-incoming router of the Linkerd daemonset pod
        # on the target app's node.
      - kind: io.l5d.k8s.daemonset
        namespace: linkerd
        port: http-incoming
        service: l5d
        # hostNetwork: true # Uncomment if using host networking (eg for CNI)
    - kind: io.l5d.k8s
      prefix: /io.l5d.k8s.h2
      transformers:
        # The daemonset transformer replaces the address of the target app with
        # the address of the h2-incoming router of the Linkerd daemonset pod
        # on the target app's node.
      - kind: io.l5d.k8s.daemonset
        namespace: linkerd
        port: h2-incoming
        service: l5d
        # hostNetwork: true # Uncomment if using host networking (eg for CNI)
    - kind: io.l5d.k8s
      prefix: /io.l5d.k8s.grpc
      transformers:
        # The daemonset transformer replaces the address of the target app with
        # the address of the grpc-incoming router of the Linkerd daemonset pod
        # on the target app's node.
      - kind: io.l5d.k8s.daemonset
        namespace: linkerd
        port: grpc-incoming
        service: l5d
        # hostNetwork: true # Uncomment if using host networking (eg for CNI)
    - kind: io.l5d.rewrite
      prefix: /portNsSvcToK8s
      pattern: "/{port}/{ns}/{svc}"
      name: "/k8s/{ns}/{port}/{svc}"

    # Telemeters export metrics and tracing data about Linkerd, the services it
    # connects to, and the requests it processes.
    telemetry:
    - kind: io.l5d.prometheus # Expose Prometheus style metrics on :9990/admin/metrics/prometheus
    - kind: io.l5d.recentRequests
      sampleRate: 0.25 # Tune this sample rate before going to production
    # - kind: io.l5d.zipkin # Uncomment to enable exporting of zipkin traces
    #   host: zipkin-collector.default.svc.cluster.local # Zipkin collector address
    #   port: 9410
    #   sampleRate: 1.0 # Set to a lower sample rate depending on your traffic volume

    # Usage is used for anonymized usage reporting.  You can set the orgId to
    # identify your organization or set `enabled: false` to disable entirely.
    usage:
      orgId: linkerd-examples-servicemesh

    # Routers define how Linkerd actually handles traffic.  Each router listens
    # for requests, applies routing rules to those requests, and proxies them
    # to the appropriate destinations.  Each router is protocol specific.
    # For each protocol (HTTP, HTTP/2, gRPC) we define an outgoing router and
    # an incoming router.  The application is expected to send traffic to the
    # outgoing router which proxies it to the incoming router of the Linkerd
    # running on the target service's node.  The incoming router then proxies
    # the request to the target application itself.  We also define HTTP and
    # HTTP/2 ingress routers which act as Ingress Controllers and route based
    # on the Ingress resource.
    routers:
    - label: http-outgoing
      protocol: http
      servers:
      - port: 4140
        ip: 0.0.0.0
      # This dtab looks up service names in k8s and falls back to DNS if they're
      # not found (e.g. for external services). It accepts names of the form
      # "service" and "service.namespace", defaulting the namespace to
      # "default". For DNS lookups, it uses port 80 if unspecified. Note that
      # dtab rules are read bottom to top. To see this in action, on the Linkerd
      # administrative dashboard, click on the "dtab" tab, select "http-outgoing"
      # from the dropdown, and enter a service name like "a.b". (Or click on the
      # "requests" tab to see recent traffic through the system and how it was
      # resolved.)
      dtab: |
        /ph  => /$/io.buoyant.rinet ;                     # /ph/80/google.com -> /$/io.buoyant.rinet/80/google.com
        /svc => /ph/80 ;                                  # /svc/google.com -> /ph/80/google.com
        /svc => /$/io.buoyant.porthostPfx/ph ;            # /svc/google.com:80 -> /ph/80/google.com
        /k8s => /#/io.l5d.k8s.http ;                      # /k8s/default/http/foo -> /#/io.l5d.k8s.http/default/http/foo
        /portNsSvc => /#/portNsSvcToK8s ;                 # /portNsSvc/http/default/foo -> /k8s/default/http/foo
        /host => /portNsSvc/http/default ;                # /host/foo -> /portNsSvc/http/default/foo
        /host => /portNsSvc/http ;                        # /host/default/foo -> /portNsSvc/http/default/foo
        /svc => /$/io.buoyant.http.domainToPathPfx/host ; # /svc/foo.default -> /host/default/foo
      client:
        kind: io.l5d.static
        configs:
        # Use HTTPS if sending to port 443
        - prefix: "/$/io.buoyant.rinet/443/{service}"
          tls:
            commonName: "{service}"

    - label: http-incoming
      protocol: http
      servers:
      - port: 4141
        ip: 0.0.0.0
      interpreter:
        kind: default
        transformers:
        - kind: io.l5d.k8s.localnode
          # hostNetwork: true # Uncomment if using host networking (eg for CNI)
      dtab: |
        /k8s => /#/io.l5d.k8s ;                           # /k8s/default/http/foo -> /#/io.l5d.k8s/default/http/foo
        /portNsSvc => /#/portNsSvcToK8s ;                 # /portNsSvc/http/default/foo -> /k8s/default/http/foo
        /host => /portNsSvc/http/default ;                # /host/foo -> /portNsSvc/http/default/foo
        /host => /portNsSvc/http ;                        # /host/default/foo -> /portNsSvc/http/default/foo
        /svc => /$/io.buoyant.http.domainToPathPfx/host ; # /svc/foo.default -> /host/default/foo

    - label: h2-outgoing
      protocol: h2
      servers:
      - port: 4240
        ip: 0.0.0.0
      dtab: |
        /ph  => /$/io.buoyant.rinet ;                       # /ph/80/google.com -> /$/io.buoyant.rinet/80/google.com
        /svc => /ph/80 ;                                    # /svc/google.com -> /ph/80/google.com
        /svc => /$/io.buoyant.porthostPfx/ph ;              # /svc/google.com:80 -> /ph/80/google.com
        /k8s => /#/io.l5d.k8s.h2 ;                          # /k8s/default/h2/foo -> /#/io.l5d.k8s.h2/default/h2/foo
        /portNsSvc => /#/portNsSvcToK8s ;                   # /portNsSvc/h2/default/foo -> /k8s/default/h2/foo
        /host => /portNsSvc/h2/default ;                    # /host/foo -> /portNsSvc/h2/default/foo
        /host => /portNsSvc/h2 ;                            # /host/default/foo -> /portNsSvc/h2/default/foo
        /svc => /$/io.buoyant.http.domainToPathPfx/host ;   # /svc/foo.default -> /host/default/foo
      client:
        kind: io.l5d.static
        configs:
        # Use HTTPS if sending to port 443
        - prefix: "/$/io.buoyant.rinet/443/{service}"
          tls:
            commonName: "{service}"

    - label: h2-incoming
      protocol: h2
      servers:
      - port: 4241
        ip: 0.0.0.0
      interpreter:
        kind: default
        transformers:
        - kind: io.l5d.k8s.localnode
          # hostNetwork: true # Uncomment if using host networking (eg for CNI)
      dtab: |
        /k8s => /#/io.l5d.k8s ;                             # /k8s/default/h2/foo -> /#/io.l5d.k8s/default/h2/foo
        /portNsSvc => /#/portNsSvcToK8s ;                   # /portNsSvc/h2/default/foo -> /k8s/default/h2/foo
        /host => /portNsSvc/h2/default ;                    # /host/foo -> /portNsSvc/h2/default/foo
        /host => /portNsSvc/h2 ;                            # /host/default/foo -> /portNsSvc/h2/default/foo
        /svc => /$/io.buoyant.http.domainToPathPfx/host ;   # /svc/foo.default -> /host/default/foo

    - label: grpc-outgoing
      protocol: h2
      servers:
      - port: 4340
        ip: 0.0.0.0
      identifier:
        kind: io.l5d.header.path
        segments: 1
      dtab: |
        /hp  => /$/inet ;                                # /hp/linkerd.io/8888 -> /$/inet/linkerd.io/8888
        /svc => /$/io.buoyant.hostportPfx/hp ;           # /svc/linkerd.io:8888 -> /hp/linkerd.io/8888
        /srv => /#/io.l5d.k8s.grpc/default/grpc;         # /srv/service/package -> /#/io.l5d.k8s.grpc/default/grpc/service/package
        /svc => /$/io.buoyant.http.domainToPathPfx/srv ; # /svc/package.service -> /srv/service/package
      client:
        kind: io.l5d.static
        configs:
        # Always use TLS when sending to external grpc servers
        - prefix: "/$/inet/{service}"
          tls:
            commonName: "{service}"

    - label: grpc-incoming
      protocol: h2
      servers:
      - port: 4341
        ip: 0.0.0.0
      identifier:
        kind: io.l5d.header.path
        segments: 1
      interpreter:
        kind: default
        transformers:
        - kind: io.l5d.k8s.localnode
          # hostNetwork: true # Uncomment if using host networking (eg for CNI)
      dtab: |
        /srv => /#/io.l5d.k8s/default/grpc ;             # /srv/service/package -> /#/io.l5d.k8s/default/grpc/service/package
        /svc => /$/io.buoyant.http.domainToPathPfx/srv ; # /svc/package.service -> /srv/service/package

    # HTTP Ingress Controller listening on port 80
    - protocol: http
      label: http-ingress
      servers:
        - port: 80
          ip: 0.0.0.0
          clearContext: true
      identifier:
        kind: io.l5d.ingress
      dtab: /svc => /#/io.l5d.k8s

    # HTTP/2 Ingress Controller listening on port 8080
    - protocol: h2
      label: h2-ingress
      servers:
        - port: 8080
          ip: 0.0.0.0
          clearContext: true
      identifier:
        kind: io.l5d.ingress
      dtab: /svc => /#/io.l5d.k8s

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: l5d
  name: l5d
  namespace: linkerd
spec:
  selector:
    matchLabels:
      name: l5d
  template:
    metadata:
      labels:
        app: l5d
        name: l5d
    spec:
      # hostNetwork: true # Uncomment to use host networking (eg for CNI)
      volumes:
      - name: l5d-config
        configMap:
          name: "l5d-config"
      containers:
      - name: l5d
        image: buoyantio/linkerd:1.4.6
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        args:
        - /io.buoyant/linkerd/config/config.yaml
        ports:
        - name: http-outgoing
          containerPort: 4140
          hostPort: 4140
        - name: http-incoming
          containerPort: 4141
        - name: h2-outgoing
          containerPort: 4240
          hostPort: 4240
        - name: h2-incoming
          containerPort: 4241
        - name: grpc-outgoing
          containerPort: 4340
          hostPort: 4340
        - name: grpc-incoming
          containerPort: 4341
        - name: http-ingress
          containerPort: 80
        - name: h2-ingress
          containerPort: 8080
        volumeMounts:
        - name: "l5d-config"
          mountPath: "/io.buoyant/linkerd/config"
          readOnly: true
      

      initContainers:
      - name: init-linkerd
        image: linkerd/istio-init:v1
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        args:
          - -p
          - "4140" # port of the Daemonset linkerd's incoming router
          - -s
          - "l5d" # linkerd Daemonset service name, uppercased
          - -m
          - "false" # set to true if running in minikube
        imagePullPolicy: IfNotPresent
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
          privileged: false # set to true for SELinux     
      
      # Run `kubectl proxy` as a sidecar to give us authenticated access to the
      # Kubernetes API.
      - name: kubectl
        image: buoyantio/kubectl:v1.14.3
        args:
        - "proxy"
        - "-p"
        - "8001"
---
apiVersion: v1
kind: Service
metadata:
  name: l5d
  namespace: linkerd
spec:
  selector:
    app: l5d
  type: LoadBalancer
  ports:
  - name: http-outgoing
    port: 4140
  - name: http-incoming
    port: 4141
  - name: h2-outgoing
    port: 4240
  - name: h2-incoming
    port: 4241
  - name: grpc-outgoing
    port: 4340
  - name: grpc-incoming
    port: 4341
  - name: http-ingress
    port: 80
  - name: h2-ingress
    port: 8080

@supermario thanks for this info. I’d like to work with you to revisit the Linkerd 2 deployment.

Linkerd 2 is the future for the project and spending time together to address those issues is going to be much more fruitful long term. Are you open to that?