๋กœ์ผ“๐Ÿพ
article thumbnail

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ๋‹ค๋ฅธ ํ”Œ๋žซํผ์ฒ˜๋Ÿผ ์ธ์ฆ(Authentication)/์ธ๊ฐ€(Athorization) ๋ฅผ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ธ์ฆ๋ฐ›์ง€ ๋ชปํ•œ ์‚ฌ์šฉ์ž๋ผ๋ฉด 401 (UnAuthorized) ๋ฅผ ์‘๋‹ต ๋ฐ›๊ณ , ์ธ์ฆ์€ ๋˜์—ˆ์ง€๋งŒ ๊ถŒํ•œ์ด ์—†๋‹ค๋ฉด 403(Forbidden) ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋˜์ฃ .

์•„์ฃผ ํ‰๋ฒ”ํ•œ ์ธ์ฆ/์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ธ์ฆ/์ธ๊ฐ€๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๊ณ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํ™˜๊ฒฝ์— ๋ฐ”๋กœ ์ ์šฉํ•  ์ˆœ ์žˆ๋Š” ๊ฑด ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋‚ธ ์š”์ฒญ์„ ์ ์šฉํ•˜๊ธฐ ์ง์ „ ํ•œ ๊ตฐ๋ฐ๋ฅผ ๋” ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ Adimission Controller ์ž…๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Adimission Controller ์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ณ , Adimission Controller ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณผ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ๐Ÿ˜Ž

 

1. Admission Controller ๊ฐ€ ๋ญ์ฃ ?


๊ณต์‹ ๋ฌธ์„œ ์— ์žˆ๋Š” Admission Controller ๊ด€๋ จ ๊ธ€์„ ๋ฒˆ์—ญํ•ด๋ณด์ž๋ฉด ์ด๋ ‡์Šต๋‹ˆ๋‹ค.

 

Admission Controller ๋Š” ํด๋Ÿฌ์Šคํ„ฐ์˜ ์‚ฌ์šฉ ๋ฐฉ์‹์„ ์ œ์–ดํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค. ์ธ์ฆ/์ธ๊ฐ€๋œ API ์š”์ฒญ์„ Admission Controller ์ด ๊ฐ€๋กœ์ฑ„์–ด ์š”์ฒญ ๊ฐœ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์š”์ฒญ์„ ๋ชจ๋‘ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒŒ์ดํŠธํ‚คํผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

Admission Controller Phases

 

์ด ๊ทธ๋ฆผ์ด ๋ฐ”๋กœ Admission Controller ์˜ Phases ์ด์ฃ . ์ธ์ฆ(Authentication)/์ธ๊ฐ€(Athorization) ๋ฅผ ๊ฑฐ์นœ ํ›„ Mutating Admission ๊ณผ Validating Admission ์ด API Request ๋ฅผ ๊ฐ€๋กœ์ฑ„๊ฒŒ ๋˜๋Š”๋ฐ ์ด 2๊ฐœ๊ฐ€ Admission Controller ์˜ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

 

๊ฐ€๋กœ์ฑˆ API Request ๋Š” WebHook ๋ฐฉ์‹์œผ๋กœ Admission Controller Server ๋กœ ๋ณด๋‚ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์—ฌ๊ธฐ์„œ ์š”์ฒญ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜์ฃ .

 

Mutating Admission ์€ ์ฃผ๋กœ API Request ์˜ ๊ฐœ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์šฉ๋„์ด๊ณ , Validating Admission ์€ ์ฃผ๋กœ API Request ๋ฅผ ๊ฑฐ๋ถ€ํ•  ์ง€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

 

๋…ผ๋ฆฌ์ ์œผ๋กœ๋Š” ์ด ๋‘˜์˜ ์—ญํ• ์ด ๊ฐ๊ฐ€ ๋‹ค๋ฅด์ง€๋งŒ Validating Admission ์—์„œ ๊ผญ ๊ฑฐ๋ถ€๋งŒ ํ•  ํ•„์š” ์—†์ด ๊ฐœ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ๋ฌด๋ฐฉํ•ฉ๋‹ˆ๋‹ค.

 

Admission Controller ์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ๋Š” LimitRanger ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ Admission Controller ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋ผ๊ณ  ๋ง์”€๋“œ๋ ธ์ฃ ? 30๊ฐœ ์ •๋„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š”๋ฐ LimitRanger ์€ ๊ทธ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

 

LimitRanger ์€ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์— ํŒŒ๋“œ๋ฅผ ๋ฐฐํฌํ•  ๋•Œ ๋งŒ์•ฝ resource ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด default resource ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ด๋†“์€ resource ๋ฅผ ๊ฐ–๊ฒŒ๋˜๊ฑฐ๋‚˜, resource ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์€ ํŒŒ๋“œ๋Š” ๋ฐฐํฌ ์ œํ•œ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

 

์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์–ด๋ ต์ง€ ์•Š์Šต๋‹ˆ๋‹ค. kube-apiserver.yaml ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€๋งŒ ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<python />
apiVersion: v1 kind: Pod metadata: annotations: kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 10.178.0.2:6443 creationTimestamp: null labels: component: kube-apiserver tier: control-plane name: kube-apiserver namespace: kube-system spec: containers: - command: - kube-apiserver - --encryption-provider-config=/etc/kubernetes/etcd/ec.yaml - --anonymous-auth=true - --advertise-address=10.178.0.2 - --allow-privileged=true - --authorization-mode=Node,RBAC - --client-ca-file=/etc/kubernetes/pki/ca.crt - --enable-admission-plugins=LimitRanger # ์ถ”๊ฐ€ ...

 

LimitRanger ๋ง๊ณ  ๋ˆˆ์—ฌ๊ฒจ๋ณผ๋งŒํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ PodSecurityPolicy ๊ฐ€ ์žˆ๋Š”๋ฐ์š”. ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ Pod ์™€ ๊ด€๋ จ๋œ ๋ณด์•ˆ ์ •์ฑ…์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค๋ฉด SecurityContext ๋Š” 1000 ์ด ์•„๋‹Œ root ๋กœ ์ƒ์„ฑํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด ํŒŒ๋“œ ์ƒ์„ฑ์„ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ๋Š” ์ •์ฑ…์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์ฃ .

 

ํ•˜์ง€๋งŒ PodSeuciryPolicy ๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค v1.21 ์—์„œ deprecated ๋˜์—ˆ๊ณ , v1.25 ์—์„  ์™„์ „ํžˆ ์‚ญ์ œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ด๋Ÿฌํ•œ ์ •์ฑ…์€ ์–ด๋–ป๊ฒŒ ์ƒ์„ฑํ•ด์„œ ์ ์šฉํ•ด์•ผ ํ• ๊นŒ์š”?

 

๋‹ต์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋งŒ๋“ค๋ฉด ๋˜์ฃ  ๐ŸคŸ

 

๊ทธ๋Ÿผ ํ•œ๋ฒˆ ๊ฐ„๋‹จํ•˜๊ฒŒ Admission Controller ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ฃ !

 

Admission Controller ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด๋„ ๋˜์ง€๋งŒ, ์ด๋ฏธ ์ž˜ ๋งŒ๋“ค์–ด์ง„ CNCF ํ”„๋กœ์ ํŠธ ์ผ๋ถ€์ธ OPA Gatekeeper ๋ผ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ๋งค์šฐ ๋ฐ€๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์ด๊ธฐ๋„ ํ•˜๊ณ , ๊ฐœ๋ฐœํ•ด์•ผํ•œ๋‹ค๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€ ๋•Œ๋ฌธ์— ์•„๋งˆ ๋งŽ์€ ๋ถ„๋“ค์ด OPA Gatekeeper ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊นŒ ๋ผ๋Š” ์ƒ๊ฐ์€ ๋“ญ๋‹ˆ๋‹ค.

๊ทธ๋ž˜๋„ ์›๋ฆฌ๋Š” ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…ํ•˜๊ณ  ์‹ถ์œผ๋‹ˆ ๋งŒ๋“ค์–ด๋ณด์ฃ .

 

 

2. Admission Controller ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž!


๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— Node.js ์˜ Express ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

Node ๋ฒ„์ „์€ 18.5 ์—์„œ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

 

Express ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค. ์ดํ›„ package.json ์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

<javascript />
"scripts": { "start": "node ./bin/www", "dev": "nodemon app start", "prod": "pm2-runtime start app.js -i 1" }

 

 

ํ”„๋กœ์ ํŠธ ๊ด€๋ จ npm ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ , ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

<bash />
npm install -i nodemon pm2 npm run dev

 

Admission Controller Server ๋Š” ๋ฐ˜๋“œ์‹œ TLS ํ†ต์‹ ์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, http ํ†ต์‹ ์ด ์•„๋‹Œ https ๋กœ ํ†ต์‹ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

 

์ฝ”๋“œ๋กœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<javascript />
const bodyParser = require('body-parser'); const express = require('express'); const fs = require('fs'); const https = require('https'); const app = express(); app.use(bodyParser.json()); # ์„œ๋ฒ„ 8443 ๋ฆฌ์Šค๋‹ const port = 8443; # tls ํ†ต์‹ ์— ์‚ฌ์šฉํ•  ca.crt, server.crt, server.key ์ฝ๊ธฐ const options = { ca: fs.readFileSync('ca.crt'), cert: fs.readFileSync('server.crt'), key: fs.readFileSync('server.key'), }; # https ํ†ต์‹  const server = https.createServer(options, app); # ์„œ๋ฒ„ ์‹คํ–‰ server.listen(port, () => { console.log(`Server running on port ${port}/`); });

 

๊ทธ๋Ÿผ ์ด๋ฒˆ์—” ca.crt, server.crt, server.key ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์ฃ .

<html />
# CA Key ์™€ CA CRT ์ƒ์„ฑ # X.509๋Š” PKI ๊ธฐ์ˆ  ์ค‘์—์„œ ๊ฐ€์žฅ ๋„๋ฆฌ ์•Œ๋ ค์ง„ ํ‘œ์ค€ ํฌ๋งท openssl req -nodes -new -x509 -keyout ca.key -out ca.crt -subj "/CN=Admission Controller Webhook Demo CA" -sha256 # ์„œ๋ฒ„ Key ์ƒ์„ฑ openssl genrsa -out server.key 2048 # server.conf ์ƒ์„ฑ cat >server.conf <<EOF [req] req_extensions = v3_req distinguished_name = req_distinguished_name prompt = no [req_distinguished_name] CN = admission-controller-server.default.svc [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = admission-controller-server.default.svc EOF # CSR ์ƒ์„ฑ openssl req -new -key server.key -out server.csr -config server.conf # Server CRT ์ƒ์„ฑ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extensions v3_req -extfile server.conf -sha256

 

์œ„ ๋ช…๋ น์–ด๋Œ€๋กœ ์ง„ํ–‰ํ•˜๋Š” ๊ฑธ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์ด์ œ health check ์šฉ ์—”๋“œํฌ์ธํŠธ์™€ webhook ์šฉ ์—”๋“œํฌ์ธํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

<javascript />
app.get('/health', (req, res) => { res.send('ok'); }); app.post('/', (req, res) => { if (req.body.request === undefined) { res.status(400).send(); return; } console.log(req.body); // DEBUGGING const { request: { uid } } = req.body; res.send({ apiVersion: "admission.k8s.io/v1", kind: "AdmissionReview", response: { uid, allowed: validate(req) } }) }); // Create Pod ์— ๋Œ€ํ•œ ์ œํ•œ function validate(req) { if (req.body['request']['object']['kind'] == 'Pod' && req.body['request']['operation'] == 'CREATE') { return false } else { return true } }

 

GET /health ๋Š” health check ์šฉ ์—”๋“œํฌ์ธํŠธ์ด๊ณ , POST / ๋Š” webhook ์šฉ ์—”๋“œํฌ์ธํŠธ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ Create Pod ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋ฅผ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, Pod ์ƒ์„ฑ์€ ์ œํ•œ๋˜์ง€๋งŒ Pod ์™ธ์— Deploy ๋‚˜ Service ๋“ฑ์€ ์ƒ์„ฑ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

์ฐธ๊ณ ๋กœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ webhook ์œผ๋กœ ๋ณด๋‚ด๋Š” Request ๊ฐ์ฒด๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. 

์ž์„ธํ•œ ์ •๋ณด๋Š” ์—ฌ๊ธฐ ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

<html />
{ "kind": "AdmissionReview", "apiVersion": "admission.k8s.io/v1", "request": { "uid": "687a5fd9-0939-4d17-a398-d80582b199f8", "kind": { "group": "", "version": "v1", "kind": "Pod" }, "resource": { "group": "", "version": "v1", "resource": "pods" }, "requestKind": { "group": "", "version": "v1", "kind": "Pod" }, "requestResource": { "group": "", "version": "v1", "resource": "pods" }, "name": "hello-pod", "namespace": "default", "operation": "CREATE", "userInfo": { "username": "kubernetes-admin", "groups": [] }, "object": { "kind": "Pod", "apiVersion": "v1", "metadata": [], "spec": [], "status": [] }, "oldObject": null, "dryRun": "false", "options": { "kind": "CreateOptions", "apiVersion": "meta.k8s.io/v1", "fieldManager": "kubectl-client-side-apply", "fieldValidation": "Strict" }, "apiVersion": "v1" } }

 

๊ทธ๋Ÿผ ์ด์ œ ์ด๋ฏธ์ง€๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก Dockerfile ์„ ์ž‘์„ฑํ•˜์ฃ .

<html />
FROM node:12.18.2 RUN mkdir /var/node COPY ./ /var/node WORKDIR /var/node RUN npm i RUN npm i -g pm2 CMD [ "npm", "run", "prod" ]

 

๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํ™˜๊ฒฝ์—์„œ ๋ฐฉ๊ธˆ ๋งŒ๋“  Adimission Controller Server ๋ฅผ ๋ฐฐํฌํ•ด๋ณด์ฃ  ๐Ÿ˜€

 

3. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์— ๋ฐฐํฌ


์ œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ๋Š” kubeadm ์œผ๋กœ ๋งŒ๋“ค์—ˆ์œผ๋ฉฐ, v1.25 ์ž…๋‹ˆ๋‹ค.

 

admission-controller-server.yaml ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

<html />
apiVersion: v1 kind: Service metadata: name: admission-controller-server spec: ports: - port: 443 protocol: TCP targetPort: 8443 selector: run: admission-controller-server --- apiVersion: v1 kind: Pod metadata: labels: run: admission-controller-server name: admission-controller-server spec: containers: - image: kingbj0429/admission-controller-server name: admission-controller-server ports: - containerPort: 8443 imagePullPolicy: Always livenessProbe: httpGet: port: 8443 path: /health scheme: HTTPS readinessProbe: httpGet: port: 8443 path: /health scheme: HTTPS

 

์—ฌ๊ธฐ์„œ ์ •๋ง์ •๋ง ์ค‘์š”ํ•œ๊ฒŒ ์žˆ๋Š”๋ฐ Service ์˜ .metadata.name ์€ ์œ„ server.crt ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ๋˜ server.conf ์— ๋ช…์‹œํ•œ CN ๊ณผ ์ด๋ฆ„์ด ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Service ์ด๋ฆ„์ด admission-controller-server ์ด๊ณ , Namespace ๊ฐ€ default ์ด๋‹ˆ admission-controller-server.default.svc ๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์ธ WebhookConfiguration ์„ ์ƒ์„ฑํ•ด์ฃผ์ฃ . mutate ์™€ valid 2 ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„  valid ๋กœ ์ƒ์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์—ฌ๊ธฐ ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

<html />
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: "pod-policy.example.com" webhooks: - name: "pod-policy.example.com" rules: - apiGroups: ["*"] apiVersions: ["*"] operations: ["CREATE"] resources: ["*"] scope: "Namespaced" clientConfig: service: namespace: "default" name: "admission-controller-server" # CN ๊ณผ ์ผ์น˜ํ•ด์•ผํ•จ caBundle: $(cat ca.crt | base64 | tr -d '\n') admissionReviewVersions: ["v1"] sideEffects: None timeoutSeconds: 5

 

๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด CREATE ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ clientConfig ์— ๋“ฑ๋ก๋œ Service ๋„๋ฉ”์ธ(admission-controller-server)์œผ๋กœ webhook ์„ ๋ณด๋‚ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋๋‚ฌ์œผ๋‹ˆ ์ œ๋Œ€๋กœ ๋˜์—ˆ๋Š” ์ง€ ํ™•์ธํ•ด๋ณด์ฃ .

 

4. Admission Controller Server ๊ฒ€์ฆ


์•„์ฃผ ์‹ฌํ”Œํ•œ Pod ๋ฅผ ์ƒ์„ฑํ•ด๋ณด์ฃ . ์ œ๋Œ€๋กœ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด ์ œํ•œ์ด ๋˜๊ฒ ์ฃ ?

<html />
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80

 

Admission Webhook Denied ๊ฐ€ ๋‚œ ๊ฑธ ๋ณด๋‹ˆ ๋ฌธ์ œ๊ฐ€ ์—†์–ด ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋Š” ์–ด๋–จ๊นŒ์š”? 

<bash />
Error from server: error when creating "nginx.yaml": admission webhook "pod-policy.example.com" denied the request without explanation

 

Deploy ๋กœ ํ…Œ์ŠคํŠธ ํ•ด๋ณด์ฃ .

<html />
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80

 

์ƒ์„ฑ์ด ์•„์ฃผ ์ž˜๋ฉ๋‹ˆ๋‹ค.

<html />
deployment.apps/nginx-deployment created

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Admission Controller ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ์ง์ ‘ Server ๋ฅผ ์ƒ์„ฑ๊นŒ์ง€ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๊ธด ๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜Ž

 

์ฝ”๋“œ๋Š” ๊นƒํ—™ ์— ์žˆ์Šต๋‹ˆ๋‹ค