暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用 minukube 部署 kubernetes admission webhook 实现 etcd pod 安全删除

51reboot运维开发 2020-08-27
377

点击上方蓝色字体,关注我们


本需求来自于一道面试题(本环境使用 centos 7)
最好使用阿里云 ec2 服务器安装 minikube,若使用本地 pc 的 vmware 可能会出现网络方面的问题。

使用如下命令安装 minikube,参见
install minikube(https://kubernetes.io/docs/tasks/tools/install-minikube/)
# curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube
# sudo cp minikube /usr/local/bin && rm minikube


启动 minikube 可能会遇到 docker 版本过旧导致启动失败的问题。默认 centos 下面 yum 安装的 docker 版本比较旧,需要安装最新 docker,更新 docker 参见
Get Docker CE for CentOS(https://docs.docker.com/engine/install/centos/)

安装特定版本的 kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x kubectl
mv kubectl /usr/local/bin


如下命令移除已经安装的 docker
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine


如下命令安装存储驱动和设置 docker stable 版本的库
yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo


使用如下命令即可更新为最新的 docker
yum install docker-ce docker-ce-cli containerd.io


管理 kubernetes 上的服务最好使用helm(本次未用到,如无需要可忽略本节),helm安装如下:

使用如下方式获取 helm 的二进制版本
Download your desired version
Unpack it (tar -zxvf helm-v2.0.0-linux-amd64.tgz)
Find the helm binary in the unpacked directory, and move it to its desired destination (mv linux-amd64/helm /usr/local/bin/helm)


tiller 安装给出了在不同 scope 下面安装 tiller 的方法,最简单的是在 cluster-admin 下面安装即可(生产环境下建议参考 helm 安装文档将权限最小化)
# cat rbac-config.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system


使用如下命令创建即可
kubectl create -f rbac-config.yaml
serviceaccount "tiller" created
clusterrolebinding "tiller" created
$ helm init --service-account tiller


admission webhook 原理
kubernetes 的认证和授权是对客户端进行认证以及对资源进行授权,但在资源的使用处理上不够细化。admission webhook 是在一种在改变资源的持久化之前(比如某些资源的创建或删除,修改等之前)的机制。参见官方资料(https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)

如下图,在部署了 admission webhook 之后,apiserver 会发送一个AdmissionReview 的 json 数据到 webhook,其中主要包含一个AdmissionRequest 的请求,AdmissionRequest.RawExtension.Raw 包含了需要处理的 kubernetes 组件(如 pod,deployment 等)的详细信息。webhook 在接收到该请求之后会根据自定义逻辑进行处理,并返回处理结果 AdmissionResponse。admission webhook 有两种处理方式:
  • MutatingAdmissionWebhook:可以修改自定义的策略,MutatingAdmissionWebhook的处理一般优先于ValidatingAdmissionWebhook,这样前者修改的内容就可以由后者进行校验

  • ValidatingAdmissionWebhook: 允许或拒绝客户自定义的策略



type AdmissionReview struct {
    metav1.TypeMeta `json:",inline"`
    // Request describes the attributes for the admission request.
    // +optional
    Request *AdmissionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"`
    // Response describes the attributes for the admission response.
    // +optional
    Response *AdmissionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"`
}

处理流程图如下,可以看到 MutatingAdmissionWebhook 的处理优先于ValidatingAdmissionWebhook

使用如下命令启动 minikube
minikube start --vm-driver=none --extra-config=apiserver.enable-admission-plugins="NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota"


使用 kubectl api-versions 查看是否支持admissionregistration.k8s.io/v1alpha1 API
In-depth introduction to Kubernetes admission webhooks 是个很好的例子,里面详细记录了创建 admission webhook 的方式。

这里参照 In-depth introduction to Kubernetes admission webhooks 实现了根据 etcd pod 角色( leader 和非 leader )来删除 pod。

首先使用webhook-create-signed-cert.sh文件来生成自签证书,后续ValidatingWebhookConfiguration 中会用到
# ./deployment/webhook-create-signed-cert.sh


部署 admission webhook
# kubectl create -f deployment/deployment.yaml
# kubectl create -f deployment/service.yaml


生成待 CA bundle 的 config 文件以及 validatingwebhook.yaml 原始文件如下
# cat ./deployment/validatingwebhook.yaml | ./deployment/webhook-patch-ca-bundle.sh > ./deployment/validatingwebhook-ca-bundle.yaml


apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  name: validation-webhook-example-cfg
  labels:
    app: admission-webhook-example
webhooks:
  - name: required-labels.banzaicloud.com
    clientConfig:
      service:
        name: admission-webhook-example-svc #service名称
        namespace: default
        path: "/validate" #访问的后缀路径
      caBundle: ${CA_BUNDLE} #上述命令生成的认证字段
    rules:
      - operations: [ "DELETE" ] #操作的动作
        apiGroups: ["apps", ""] #api groups
        apiVersions: ["v1"] #api version
        resources: ["pods"] #操作的资源
    namespaceSelector:
      matchLabels:
        admission-webhook-example: enabled # 限制default的命名空间


给 default namespace 打上标签
$ kubectl label namespace default admission-webhook-example=enabled


创建 ValidatingWebhookConfiguration
$ kubectl create -f deployment/validatingwebhook-ca-bundle.yaml


admission-webhook-example/build 用于编译和生成容器镜像
etcd 的部署直接使用 admission-webhook-example\deployment\etcd 中的配置文件即可,这样在删除 etcd 的 leader 时会显示如下内容

admission webhook 的实现只有2个文件,main.go 和 webhook.go。main.go 中通过 mux.HandleFunc("/validate", whsvr.serve) 来启动一个 http 服务处理路径 /validate (对应 validatingwebhook.yaml 的webhooks.clientConfig.service.path) 的请求。主要逻辑是现在函数 func (whsvr *WebhookServer) validate(ar *v1beta1.AdmissionReview) *v1beta1.AdmissionRespons中

FAQ:


执行 yum install -y socat 可解决如下问题:

an error occurred forwarding 40546 -> 44134: error forwarding port 44134 to pod 3ea221f842e1446a5fd9da9fc29e7e415a1ecb6dd6d07c56f64fb4788f2c3915, uid : unable to do port forwarding: socat not found.



TIPS:


使用如下方式可以安装 etcdctl 命令行工具
# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/coreos/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

/tmp/etcd-download-test/etcd --version
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl version
# start a local etcd server
/tmp/etcd-download-test/etcd

# write,read to etcd
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl --endpoints=localhost:2379 put foo bar
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl --endpoints=localhost:2379 get foo


go get -u github.com/golang/dep/cmd/dep 安装 dep
go 安装方式如下:
安装包地址:https://golang.google.cn/dl/
安装go方式:tar -C /usr/local -xzf go1.11.2.linux-amd64.tar.gz 注意要安装完整包,不能只是bin目录
环境变量配置:
export GOPATH=/root/go
export GOROOT/usr/local/go
export PATH=$PATH:$GOROOT/bin/:$GOPATH/bin


etcdv3 的 API 使用可以参考 package clientv3
mutate webhook 的使用参见 k8s-mutate-webhook
 
参考:
  • https://github.com/helm/helm/blob/master/docs/install.md

  • https://container-solutions.com/some-admission-webhook-basics/

  • https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/

  • https://github.com/kubernetes/kubernetes/tree/master/test/e2e/testing-manifests/statefulset/etcd

  • https://github.com/morvencao/kube-mutating-webhook-tutorial/blob/master/medium-article.md



出处:http://dwz.date/b5Mv

付费社群、K8S课程详情
扫码咨询>>>


整理 kubernetes 各种问题汇总

Istio 故障注入之中止(httpStatus)

Istio 故障注入之延时(fixedDelay)

Kubernetes 使用 metric-server 让 HPA 弹性伸缩运行

运维精华



文章转载自51reboot运维开发,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论