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