k8s sidecar开发-webhook开发

王宏深
2023-12-01

1.首先需要申请一个secret,用来在进行webhook的时候apiserver访问我们的webhook服务器的时候进行证书认证。

[ -z ${service} ] && service=logcar-service
[ -z ${secret} ] && secret=logcar-secret
[ -z ${namespace} ] && namespace=kube-system

if [ ! -x "$(command -v openssl)" ]; then
    echo "openssl not found"
    exit 1
fi

csrName=${service}.${namespace}
tmpdir=$(mktemp -d)
echo "creating certs in tmpdir ${tmpdir} "

cat <<EOF >> ${tmpdir}/csr.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = CN
ST = HangZhou
L = LA
O = Personal
OU = King
CN = ${service}.${namespace}.svc

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ${service}.${namespace}.svc

[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
EOF

openssl req -x509 -nodes -new -sha256 -days 3650 -newkey rsa:2048 -subj "/CN=${service}.${namespace}.svc" \
  -keyout ${tmpdir}/ca.key \
  -out ${tmpdir}/ca.crt
openssl genrsa -out ${tmpdir}/server.key 2048
openssl req -new -key ${tmpdir}/server.key -out ${tmpdir}/server.csr -config ${tmpdir}/csr.conf
openssl x509 -req -in ${tmpdir}/server.csr -CA ${tmpdir}/ca.crt -CAkey ${tmpdir}/ca.key \
  -CAcreateserial -out ${tmpdir}/server.crt -days 3650 \
  -extensions v3_ext -extfile ${tmpdir}/csr.conf

kubectl create secret generic ${secret} -n ${namespace} \
  --from-file=${tmpdir}/ca.crt \
  --from-file=${tmpdir}/server.key \
  --from-file=${tmpdir}/server.crt

2.接着是一些webhook需要使用到的serviceAccount,rbac和service。

apiVersion: v1
kind: Service
metadata:
  name: logcar-service
  namespace: kube-system
spec:
  selector:
    app: webhook
  ports:
    - port: 18090
      targetPort: 18090
  type: NodePort
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sidecar-sa
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: sidecar-role
rules:
  - apiGroups: [""]
    resources: ["pods","nodes","configmaps","secret","serviceaccounts"]
    verbs: ["get","list","watch","update","create"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get","list","watch","update","create"]
  - apiGroups: ["batch"]
    resources: ["job"]
    verbs: ["get","list","watch","update","create"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["roles","rolebindings"]
    verbs: ["get","list","watch","update","create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sidecar-bind
subjects:
  - kind: ServiceAccount
    name: sidecar-sa
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: sidecar-role
  apiGroup: rbac.authorization.k8s.io

3.接着就可以添加webhook了。

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: webhook-config
  namespace: kube-system
  labels:
    app: webhook
webhooks:
  - name: ${service}.${namespace}.svc
    clientConfig:
      service:
        name: logcar-service
        namespace: kube-system
        path: "/sidecar-mutating"
        port: 18090
      caBundle: $(kubectl get secret ${secret} -n ${namespace} -o jsonpath='{.data.ca\.crt}')
    rules:
      - apiGroups: [ "apps" ]
        apiVersions: [ "v1" ]
        operations: [ "CREATE","UPDATE" ]
        resources: [ "deployments" ]
        scope: "*"
      - apiGroups: [ "" ]
        apiVersions: [ "v1" ]
        operations: [ "CREATE","UPDATE" ]
        resources: [ "pods" ]
        scope: "*"
      - apiGroups: [ "batch" ]
        apiVersions: [ "v1" ]
        operations: [ "CREATE","UPDATE" ]
        resources: [ "jobs" ]
        scope: "*"
    admissionReviewVersions: ["v1", "v1beta1"]
    sideEffects: None
    timeoutSeconds: 10

4.接着编写webhook的代码。

func (l *LogCarWebhook) Run() {
	mux := http.NewServeMux()
    //只要把webhookconfig里面的地址写进去就可以
	mux.HandleFunc("/sidecar-mutating", l.Inject)

	fmt.Println("sidecar running in https:0.0.0.0:18090")
	err := http.ListenAndServeTLS(":18090", l.config.CertFile, l.config.KeyFile, mux)
	if err != nil {
		panic(err)
	}
}

 5.最后把代码部署上去就可以了。需要注意这里要把前面的secret mount到pod里面,https服务起来的时候要使用。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: logcar-webhook
  namespace: kube-system
  labels:
    app: webhook
spec:
  replicas: 1
  template:
    metadata:
      name: logcar-pod
      labels:
        app: webhook
    spec:
      containers:
        - name: webhook-app
          image: yh960124/logcarwebhook
          imagePullPolicy: Always
          volumeMounts:
            - name: webhook-certs
              mountPath: /etc/webhook/certs
              readOnly: true
          ports:
            - containerPort: 18090
              protocol: TCP
      volumes:
        - name: webhook-certs
          secret:
              secretName: ${secret}
      serviceAccountName: sidecar-sa
  selector:
    matchLabels:
      app: webhook

点击查看所有代码

 类似资料: