首页 > 其他分享 >K8S集群ImagePolicyWebhook配置

K8S集群ImagePolicyWebhook配置

时间:2024-11-21 17:07:24浏览次数:1  
标签:ImagePolicyWebhook image webhook cert nginx json 集群 policy K8S

ImagePolicyWebhook用于限制节点调用某个镜像

  1. 环境查看
    系统环境
# cat /etc/redhat-release 
Rocky Linux release 9.3 (Blue Onyx)
# uname -a
Linux Rocky9K8SMaster003021 5.14.0-362.18.1.el9_3.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Sun Feb 11 13:49:23 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

软件环境

# kubectl version
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.25.16
WARNING: version difference between client (1.30) and server (1.25) exceeds the supported minor version skew of +/-1
  1. 配置
    本次已限制nginx镜像为例
    安装go
# yum -y install go

编写go语言用于限制nginx

# cat webhook.go 
package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
)

// AdmissionReview 是 Webhook 接收到的请求的结构
type AdmissionReview struct {
Request struct {
Kind       string `json:"kind"`
Object     struct {
Spec struct {
Containers []struct {
Name  string `json:"name"`
Image string `json:"image"`
} `json:"containers"`
} `json:"spec"`
} `json:"object"`
} `json:"request"`
}

type AdmissionResponse struct {
UID     string `json:"uid"`
Allowed bool   `json:"allowed"`
Result  struct {
Message string `json:"message"`
} `json:"status"`
}

func validate(w http.ResponseWriter, r *http.Request) {
var admissionReview AdmissionReview
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&admissionReview); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

// 默认 AdmissionResponse
response := AdmissionResponse{
UID:     admissionReview.Request.Kind,
Allowed: true,
}

// 检查容器镜像
for _, container := range admissionReview.Request.Object.Spec.Containers {
if strings.Contains(container.Image, "nginx") {
// 如果镜像是 nginx,拒绝请求
response.Allowed = false
response.Result.Message = fmt.Sprintf("Forbidden image: %s", container.Image)
break
}
}

// 将结果返回给 Kubernetes API Server
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(&response); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func main() {
http.HandleFunc("/validate", validate)
port := "443" // Webhook 通常监听 HTTPS 端口
log.Printf("Starting Webhook server on port %s", port)
log.Fatal(http.ListenAndServeTLS(":"+port, "/etc/webhook/cert/cert.pem", "/etc/webhook/cert/key.pem", nil))
}

初始化go

# go mod init image-policy-webhook

初始之后会在当前目录生成以下文件

# cat go.mod 
module image-policy-webhook

go 1.22.7

自建证书

# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=webhook.default.svc"

在当前目录生成key.pem和cert.pem证书
编写Dockerfile文件

# cat Dockerfile 
# 基础镜像使用 golang
FROM golang:1.22-alpine AS builder

# 设置工作目录
WORKDIR /app

# 将本地代码复制到容器中
COPY . .
RUN mkdir -p /etc/webhook/cert
ADD key.pem /etc/webhook/cert/
ADD cert.pem /etc/webhook/cert/
# 编译 Go 程序
RUN go build -o webhook .

# 使用更小的基础镜像
FROM alpine:latest

RUN mkdir -p /etc/webhook/cert
ADD key.pem /etc/webhook/cert/
ADD cert.pem /etc/webhook/cert/
# 安装所需的 CA 证书等依赖
RUN apk add --no-cache ca-certificates

# 复制编译好的程序
COPY --from=builder /app/webhook /webhook

# 配置容器启动命令
CMD ["/webhook"]

打包镜像推送至私有仓库

#  docker build -t you-harbor-url/image-policy-webhook .
#  docker push you-harbor-url/image-policy-webhook .

部署deployment

# cat webhook-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: image-policy-webhook
spec:
  replicas: 1
  selector:
    matchLabels:
      app: image-policy-webhook
  template:
    metadata:
      labels:
        app: image-policy-webhook
    spec:
      containers:
        - name: image-policy-webhook
          image: your-harbor-url/image-policy-webhook:latest
          ports:
            - containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
  name: image-policy-webhook
spec:
  ports:
    - port: 443
      targetPort: 443
  selector:
    app: image-policy-webhook

部署

# kubectl apply -f webhook-deployment.yaml 

部署ValidatingWebhookConfiguration

# cat image-policy-webhook-configuration.yaml 
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: image-policy-webhook
webhooks:
  - name: imagepolicy.webhook.example.com
    clientConfig:
      service:
        name: image-policy-webhook
        namespace: default
        path: "/validate/images"
      caBundle: 
    rules:
      - operations: ["CREATE", "UPDATE"]
        apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]
    admissionReviewVersions: ["v1"]
    sideEffects: None

部署

#  kubectl apply -f image-policy-webhook-configuration.yaml

部署完毕之后使用以下Pod测试

#  cat nginx-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest

部署拒绝提示如下

# kubectl apply -f nginx-pod.yaml 
Error from server (InternalError): error when creating "nginx-pod.yaml": Internal error occurred: failed calling webhook "imagepolicy.webhook.example.com": failed to call webhook: Post "https://image-policy-webhook.default.svc:443/validate/images?timeout=10s": dial tcp 10.43.55.46:443: connect: connection refused

注意:

k8s集群版本需要1.19以上,在1.13版本测试无法部署
部署限制执行已经调度的nginx镜像不受影响

标签:ImagePolicyWebhook,image,webhook,cert,nginx,json,集群,policy,K8S
From: https://www.cnblogs.com/minseo/p/18561167

相关文章

  • 使用简单实验体验k8s的热升级机制
    热升级pod负载均衡的容错基本可以了,现在考虑要升级一下这个容器,把其中的test.go修改一下,返回hello,world的同时打印一下HOSTNAME。packagemainimport("fmt""net/http""os")funcmain(){fmt.Println("startmain")//从环境变量取ho......
  • 【K8S系列】imagePullSecrets配置正确,但docker pull仍然失败,进一步排查详细步骤
    如果imagePullSecrets配置正确,但在执行dockerpull命令时仍然失败,可能存在以下几种原因。以下是详细的排查步骤和解决方案。1.检查Docker登录凭证确保你使用的是与imagePullSecrets中相同的凭证进行Docker登录:1.1直接登录在命令行中,执行以下命令:docker......
  • KubeSphere 最佳实战:K8s 构建高可用、高性能 Redis 集群实战指南
    首发:运维有术本指南将逐步引导您完成以下关键任务:安装Redis:使用StatefulSet部署Redis。自动或手动配置Redis集群:使用命令行工具初始化Redis集群。Redis性能测试:使用Redis自带的Benchmark工具进行性能测试。Redis图形化管理:安装并配置RedisInsight。通过本......
  • 【Redis集群实战】Redis 以及 Redis Sentinel 的 Docker部署
    Redis基本说明这里我是用的是docker。既然使用docker那么就需要配置两个组件一个Redis一个RedisSentinel我们可以使用docker-compose来启动一组docker安装docker-compose下载docker-compose安装包这里面直接从github下载。并且放在了/usr/local/bin/docker-c......
  • docker搭建hadoop集群linuxcentos(为分布式、完全分布式)
    docker搭建hadoop集群linuxcentos(为分布式、完全分布式) 第1章写在前面必读1.1Hadoop生态简单说明说明:hadoop只是一个存储数据的平台,mapreduce是一个计算框架,需要编程人员去编写处理数据的程序。然后hadoop是一个生态,就是说在其上还运行着hbase数据库,sqoop,shark等等工具,这样才......
  • h基于docker搭建hadoop+hive+spark+hbase+zookeeper+scale集群adoop集群搭建(docker)
     基于docker搭建hadoop+hive+spark+hbase+zookeeper+scale集群 1、设置主机上的虚拟缓存当本地内存不足时,可以使用虚拟内存将一些内存数据转移到硬盘上,从而扩展计算机的内存容量。这样可以让计算机运行更复杂、更占用内存的程序,不会出现内存不足的情况。减轻物理存储器......
  • XXL-JOB快速入门(什么是XXL-JOB、部署XXL-JOB、在SpringBoot项目中接入XXL-JOB、XXL-JO
    文章目录1.分布式任务调度2.@Scheduled注解的局限3.什么是XXL-JOB4.通过源码部署调度中心4.1下载源码4.2源码说明4.3运行数据库脚本4.4补充:xxl_job数据库中八张表的作用4.5调度中心配置4.5.1数据库相关配置4.5.2日志相关配置4.6启动调度中心4.7访问调度中......
  • 1000+节点、200+集群,Slack如何利用Karpenter降本增效?
    原文首发于云妙算Slack是一款AI工作管理和协作平台。随着业务需求的增长,Slack对其内部计算编排平台进行了重大改造,以增强可扩展性、提高效率并降低成本。该内部平台的代号为“Bedrock”,基于AmazonEKS和Karpnter构建。通过利用Bedrock,Slack将容器部署和管理简化为单......
  • k8s阶段02 namespace,pod资源及命令, pod资源配置(应用监控,资源需求和限制), 多容器p
    namespaceNamespace:名称空间,命名空间资源对象名称隔离www.google.com,www.magedu.com资源类型:名称空间级别:必须属于某个名称空间-nNAMESPACE_NAME--namespaceNAMESPACE_NAME集群级别:不属于任......
  • Quartz集群增强版_02.任务轮询及优化❤️
    Quartz集群增强版_02.任务轮询及优化转载请著名出处https://www.cnblogs.com/funnyzpc/p/18555665开源地址https://github.com/funnyzpc/quartz    任务轮询的主要工作是按固定频度(时间5s)去执行项表捞未来5s内将要执行的任务,轮询这些任务待到执行时间点时将任务扔到......