ïŒã€ã³ã¿ãŒãããã§çºèŠãããGordon A. Maxwellã«ããåçãïŒ
ãµã€ãã«ãŒã³ã³ãããŒãšãµãŒãã¹ã¡ãã·ã¥ã®ç 究ãå§ãããšããããŒã¡ã«ããºã ãã©ã®ããã«æ©èœããããç解ããå¿ èŠããããŸãã-ãµã€ãã«ãŒã³ã³ãããŒã®èªåæ¿å ¥ã å®éãIstioãConsulãªã©ã®ã·ã¹ãã ã䜿çšããŠããå Žåãã¢ããªã±ãŒã·ã§ã³ã§ã³ã³ãããŒããããã€ãããšããã§ã«æ§æãããŠããEnvoyã³ã³ãããŒããããã«çªç¶è¡šç€ºãããŸãïŒConduitã§ãåæ§ã®ç¶æ³ãçºçããŸãã ãªã«ïŒ ã©ããã£ãŠïŒ ããã§ç§ã®ç 究ãå§ãŸããŸãã...
ç¥ããªã人ã«ãšã£ãŠã¯ããµã€ãã«ãŒã³ã³ããã¯ãäœããã®æ¹æ³ã§ãã®ã¢ããªã±ãŒã·ã§ã³ããæ¯æŽãããããã«ãã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ããã®é£ã«ãããã€ãããã³ã³ããã§ãã ãã®ãããªäœ¿çšã®äŸã¯ããã©ãã£ãã¯ã管çããTLSã»ãã·ã§ã³ãçµäºããããã®ãããã·ããã°ãšã¡ããªãã¯ãã¹ããªãŒãã³ã°ããããã®ã³ã³ãããã»ãã¥ãªãã£åé¡ãã¹ãã£ã³ããããã®ã³ã³ãããªã©ã§ã...æ©èœã
ç¶è¡ããåã«ãç§ã®æåŸ ãæŠèª¬ããŸãã ãã®èšäºã®ç®çã¯ãDockerãKubernetesããµãŒãã¹ã¡ãã·ã¥ãªã©ã®è€éããšäœ¿çšã·ããªãªã説æããããšã§ã¯ãªãããããã®ãã¯ãããžãŒã®æ©èœãæ¡åŒµãã1ã€ã®åŒ·åãªã¢ãããŒãã瀺ãããšã§ãã ãã®èšäºã¯ããããã®ãã¯ãããžãŒã®äœ¿çšã«ãã§ã«ç²ŸéããŠããããŸãã¯å°ãªããšããããã«ã€ããŠå€ããèªãã 人ã察象ãšããŠããŸãã å®çšçãªéšåãå®éã«è©Šãã«ã¯ãDockerãšKubernetesãæ¢ã«æ§æãããŠãããã·ã³ãå¿ èŠã§ãã ãããè¡ãæãç°¡åãªæ¹æ³ã¯ã httpsïŒ//docs.docker.com/docker-for-windows/kubernetes/ ïŒDocker for Macã§åäœããWindowsããã¥ã¢ã«ïŒã§ãã ïŒæ³šperev .: Linuxããã³* nixã·ã¹ãã ã®ãŠãŒã¶ãŒã®ä»£æ¿ãšããŠã MinikubeãæäŸã§ããŸããïŒ
å šäœå
ãŸããKubernetesãèŠãŠã¿ãŸãããã
CC BY 4.0ã§ã©ã€ã»ã³ã¹ãããKube Arch
Kubernetesã«äœãããããã€ããå Žåã¯ããªããžã§ã¯ããkube-apiserverã«éä¿¡ããå¿ èŠããããŸãã ããã¯ã»ãšãã©ã®å ŽåãåŒæ°ãŸãã¯YAMLãã¡ã€ã«ãkubectlã«æž¡ãããšã§è¡ãããŸãã ãã®å ŽåãAPIãµãŒããŒã¯ããã€ãã®æ®µéãçµãŠãããããŒã¿ãetcdã«çŽæ¥é 眮ãã察å¿ããã¿ã¹ã¯ãã¹ã±ãžã¥ãŒã«ããŸãã
ãã®ã·ãŒã±ã³ã¹ã¯ããµã€ãã«ãŒã³ã³ããã®æ¿å ¥ã®ä»çµã¿ãç解ããããã«éèŠã§ãã ç¹ã«ãKubernetesããªããžã§ã¯ããä¿åããåã«æ€èšŒããå¿ èŠã«å¿ããŠå€æŽããã¢ãããã·ã§ã³ã³ã³ãããŒã«ã«æ³šæãæãå¿ èŠããããŸãïŒãã®æé ã®è©³çŽ°ã«ã€ããŠã¯ã ãã®èšäºã® ãã¢ã¯ã»ã¹ã³ã³ãããŒã«ãã®ç« ãåç §ããŠãã ããïŒ ã Kubernetesã§ã¯ããŠãŒã¶ãŒå®çŸ©ã®æ€èšŒãšå€æŽãå®è¡ã§ããwebhookãç»é²ããããšãã§ããŸãã
ãã ããããã¯ãäœæããã³ç»é²ããããã»ã¹ã¯ããã»ã©åçŽã§ã¯ãªããååã«ææžåãããŠããŸãã IstioãšConsulã®ã³ãŒããåæããã ãã§ãªããããã¥ã¡ã³ãã®èªã¿åããšåèªã¿åãã«æ°æ¥éãè²»ããå¿ èŠããããŸããã ãŸããäžéšã®APIå¿çã®ã³ãŒãã«ã€ããŠã¯ãå°ãªããšãåæ¥ãã©ã³ãã ãªè©Šè¡é¯èª€ãç¹°ãè¿ããŸããã
çµæãéæãããåŸããããçãããšå ±æããªãã®ã¯äžå ¬å¹³ã ãšæããŸãã ã·ã³ãã«ã§ãããšåæã«å¹æçã§ãã
ã³ãŒã
webhookãšããååã¯ãKubernetesã§å®çŸ©ãããAPIãå®è£ ããHTTPãšã³ããã€ã³ãã§ãã ãããã€ã¡ã³ããåŠçããåã«KubernetesãåŒã³åºãããšãã§ããAPIãµãŒããŒãäœæããŠããŸãã ããã§ã¯ããã€ãã®äŸããå©çšã§ããªããããããã§ã®å°é£ã«å¯ŸåŠããå¿ èŠããããŸããããã®ãã¡ã®ããã€ãã¯Kubernetesã®åäœãã¹ãã§ããããã®ä»ã¯å·šå€§ãªã³ãŒãããŒã¹ã®éäžã«é ãããŠããŸã...ãããŠãã¹ãŠGoã§èšè¿°ãããŠããŸãã ããããç§ã¯ããæé ãªãªãã·ã§ã³ãéžæããŸãã-Node.jsïŒ
const app = express(); app.use(bodyParser.json()); app.post('/mutate', (req, res) => { console.log(req.body) console.log(req.body.request.object) let adminResp = {response:{ allowed: true, patch: Buffer.from("[{ \"op\": \"add\", \"path\": \"/metadata/labels/foo\", \"value\": \"bar\" }]").toString('base64'), patchType: "JSONPatch", }} console.log(adminResp) res.send(adminResp) }) const server = https.createServer(options, app);
ïŒ index.js ïŒ
APIãžã®ãã¹-ãã®å Žå
/mutate
ã¯ä»»æã§ãïŒå°æ¥çã«Kubernetesã«æž¡ãããYAMLã«ã®ã¿å¯Ÿå¿ããå¿ èŠããããŸãïŒã 圌ã«ãšã£ãŠãAPIãµãŒããŒããåãåã£ãJSONãèŠãŠç解ããããšãéèŠã§ãã ãã®å ŽåãJSONããäœãåŒãåºãââããšã¯ãããŸããããä»ã®ã·ããªãªã§ã¯åœ¹ã«ç«ã€ãããããŸããã äžèšã®ã³ãŒãã§ã¯ãJSONãæŽæ°ããŸãã ããã«ã¯2ã€ã®ããšãå¿ èŠã§ãã
- JSONããããåŠã³ãç解ããŠãã ããã
- JSONãããåŒãbase64ã§ãšã³ã³ãŒãããããã€ãã®é åã«æ£ããå€æããŸãã
ãããå®äºããããéåžžã«åçŽãªãªããžã§ã¯ãã䜿çšããŠAPIãµãŒããŒã«å¿çãæž¡ãã ãã§ãã ãã®å Žåãã©ãã«
foo=bar
ãããã«è¿œå ã
foo=bar
ã
å±é
ããŠãKubernetes APIãµãŒããŒããã®ãªã¯ãšã¹ããåãå ¥ããŠãããã«å¿çããã³ãŒãããããŸãããã©ã®ããã«ãããã€ããã®ã§ããããïŒ ãããŠãKubernetesã«ãããã®ãªã¯ãšã¹ãããªãã€ã¬ã¯ããããæ¹æ³ã¯ïŒ ãã®ãããªãšã³ããã€ã³ãã¯ãKubernetes APIãµãŒããŒã«ã¢ã¯ã»ã¹ã§ããå Žæã§ããã°ã©ãã«ã§ãå±éã§ããŸãã æãç°¡åãªæ¹æ³ã¯ãã³ãŒããKubernetesã¯ã©ã¹ã¿ãŒèªäœã«ãããã€ããããšã§ããããã¯ãã®äŸã§è¡ããŸãã ãã®äŸãã§ããã ãç°¡åã«ããããšããã®ã§ããã¹ãŠã®ã¢ã¯ã·ã§ã³ã§Dockerãškubectlã®ã¿ã䜿çšããŸãã ã³ãŒããå®è¡ããã³ã³ãããäœæããããšããå§ããŸãããã
FROM node:8 USER node WORKDIR /home/node COPY index.js . COPY package.json . RUN npm install # TLS CMD node index.js
ïŒ Dockerfile ïŒ
ã©ããããããã§ã¯ãã¹ãŠãéåžžã«ç°¡åã§ãã ããŒãããã³ãã¥ããã£ã€ã¡ãŒãžãååŸããããã«ã³ãŒããããããããŸãã ããã§ãç°¡åãªã¢ã»ã³ããªãå®è¡ã§ããŸãã
docker build . -t localserver
次ã®ã¹ãããã¯ãKubernetesã§å±éãäœæããããšã§ãã
apiVersion: apps/v1 kind: Deployment metadata: name: webhook-server spec: replicas: 1 selector: matchLabels: component: webhook-server template: metadata: labels: component: webhook-server spec: containers: - name: webhook-server imagePullPolicy: Never image: localserver
ïŒ deployment.yaml ïŒ
æ°ããäœæãããç»åãã©ã®ããã«ç€ºãããã«æ³šç®ããŠãã ãã ãããããKubernetesã®ãµãŒãã¹ã«æ¥ç¶ã§ããä»ã®äœãã§ããããŸãã 次ã«ããã®ãµãŒãã¹ãå®çŸ©ããŸãã
apiVersion: v1 kind: Service metadata: name: webhook-service spec: ports: - port: 443 targetPort: 8443 selector: component: webhook-server
ãããã£ãŠãKubernetesã§ã¯ãã³ã³ãããæãå éšåã§ãšã³ããã€ã³ãã衚瀺ãããŸãã æåŸã®ã¹ãããã¯ãKubernetesã«ãå€æŽãå ããæºåãã§ãããšãã«APIãµãŒããŒã«ãã®ãµãŒãã¹ãåŒã³åºãããã«æ瀺ããããšã§ãã
ïŒ hook.yaml ïŒapiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: name: webhook webhooks: - name: webhook-service.default.svc failurePolicy: Fail clientConfig: service: name: webhook-service namespace: default path: "/mutate" # base64- rootCA.crt # `cat rootCA.crt | base64 | tr -d '\n'` # . caBundle: "==" rules: - operations: [ "CREATE" ] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"]
ããã§ã®ååãšãã¹ã¯ä»»æã§ãããã§ããã ãæå³ã®ãããã®ã«ããããšããŸããã ãã¹ãå€æŽãããšãJavaScriptã®å¯Ÿå¿ããã³ãŒããå€æŽããå¿ èŠããããŸãã Webhook
failurePolicy
ã
failurePolicy
-ããã¯ããšã©ãŒãè¿ãã倱æããå Žåã«ãªããžã§ã¯ããä¿åãããã©ããã決å®ããŸãã ãã®å ŽåãåŠçãç¶è¡ããªãããã«Kubernetesã«æ瀺ããŠããŸãã æåŸã«ãã«ãŒã«ïŒKubernetesããã®ã¢ã¯ã·ã§ã³ãæåŸ ããAPIã³ãŒã«ã«å¿ããŠå€æŽãããŸãã ãã®å Žåããµã€ãã«ãŒã³ã³ãããŒã®æ¿å ¥ããšãã¥ã¬ãŒãããããšããŠãããããããããäœæããããã«ãªã¯ãšã¹ããã€ã³ã¿ãŒã»ããããå¿ èŠããããŸãã
以äžã§ãïŒ ãšãŠãã·ã³ãã«ã§ãã...ã»ãã¥ãªãã£ã¯ã©ãã§ããïŒ RBACã¯ããã®èšäºã§ã¯åãäžããŠããªãåŽé¢ã®1ã€ã§ãã Docker for Windows / Macã«ä»å±ã®MinikubeãŸãã¯Kubernetesã§ãµã³ãã«ãå®è¡ããŠãããšæããŸãã ãã ããå¥ã®å¿ èŠãªèŠçŽ ã«ã€ããŠèª¬æããŸãã Kubernetes APIãµãŒããŒã¯HTTPSã®ãšã³ããã€ã³ãã®ã¿ã«ã¢ã¯ã»ã¹ãããããã¢ããªã±ãŒã·ã§ã³ã«ã¯SSL蚌ææžãå¿ èŠã§ãã ãŸããã«ãŒã蚌ææžã®èšŒææ©é¢ã誰ã§ããããKubernetesã«äŒããå¿ èŠããããŸãã
TLS
ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã®ã¿ãç®çãšããŠïŒ!!!ïŒã
Dockerfile
ã«ã³ãŒããè¿œå ããŠã«ãŒãCAãäœæããããã䜿çšããŠèšŒææžã«çœ²åããŸãã
RUN openssl genrsa -out rootCA.key 4096 RUN openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt \ -subj "/C=US/ST=New Jersey/L=Princeton /O=Dow Jones/OU=PIB/CN=*.default.svc/emailAddress=scott.rahner@dowjones.com" RUN openssl genrsa -out webhook.key 4096 RUN openssl req -new -key webhook.key -out webhook.csr \ -subj "/C=US/ST=New Jersey/L=Princeton /O=Dow Jones/OU=PIB/CN=webhook-service.default.svc/emailAddress=scott.rahner@dowjones.com" RUN openssl x509 -req -in webhook.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out webhook.crt -days 1024 -sha256 RUN cat rootCA.crt | base64 | tr -d '\n'
ïŒ Dockerfile ïŒ
泚ïŒæåŸã®æé ã¯ãbase64ã§ãšã³ã³ãŒããããã«ãŒãCAãå«ã1è¡ã衚瀺ããããšã§ãã ããã¯ãããã¯ãæ§æããããã«å¿ èŠãªãã®ã§ãããããã£ãŠã以éã®ãã¹ãã§ã¯ããã®è¡ã
caBundle
ãã¡ã€ã«ã®
caBundle
ãã£ãŒã«ãã«å¿ ãã³ããŒããŠ
caBundle
ã
Dockerfile
ã¯èšŒææžã
WORKDIR
ã«çŽæ¥ã¹ããŒãããããJavaScriptã¯ãããã蚌ææžãååŸããŠãµãŒããŒã«äœ¿çšããŸãã
const privateKey = fs.readFileSync('webhook.key').toString(); const certificate = fs.readFileSync('webhook.crt').toString(); //⊠const options = {key: privateKey, cert: certificate}; const server = https.createServer(options, app);
ããã§ãã³ãŒãã¯HTTPSã®èµ·åããµããŒãããKubernetesã«åœç€Ÿã®æåšå°ãšä¿¡é ŒããèªèšŒæ©é¢ãäŒããŸããã ãã¹ãŠãã¯ã©ã¹ã¿ãŒã«åã蟌ãããã ãã«æ®ããŸãã
kubectl create -f deployment.yaml kubectl create -f service.yaml kubectl create -f hook.yaml
èŠçŽãã
-
Deployment.yaml
ã¯ãHTTPSãä»ããŠããã¯APIãæäŸããã³ã³ãããŒãèµ·åãããªããžã§ã¯ããå€æŽããJSONããããè¿ããŸãã -
Service.yaml
ã¯ãã³ã³ããã®ãšã³ããã€ã³ãwebhook-service.default.svc
æäŸããŸãã -
Hook.yaml
ã¯ãhttps://webhook-service.default.svc/mutate
å ŽæãAPIãµãŒããŒã«æ瀺ããŸãã
ããžãã¹ã§ãã£ãŠã¿ãŸãããïŒ
ãã¹ãŠãã¯ã©ã¹ã¿ãŒã«ãããã€ãããŸã-æ°ããããã/ãããã€ã¡ã³ããè¿œå ããããšã§å®è¡ããã³ãŒãã®ã¢ã¯ã·ã§ã³ãè©Šãæã§ãã ãã¹ãŠãæ£åžžã«æ©èœããå Žåãããã¯ã¯è¿œå ã®ã©ãã«
foo
ãè¿œå ããå¿ èŠããããŸãã
apiVersion: apps/v1 kind: Deployment metadata: name: test spec: replicas: 1 selector: matchLabels: component: test template: metadata: labels: component: test spec: containers: - name: test image: node:8 command: [ "/bin/sh", "-c", "--" ] args: [ "while true; do sleep 30; done;" ]
ïŒ test.yaml ïŒ
kubectl create -f test.yaml
ããããŸãã
deployment.apps test created
...ããŸããããŸãããïŒ
kubectl describe pods test Name: test-6f79f9f8bd-r7tbd Namespace: default Node: docker-for-desktop/192.168.65.3 Start Time: Sat, 10 Nov 2018 16:08:47 -0500 Labels: component=test foo=bar
ãããïŒ
test.yaml
ã¯åäžã®ã©ãã«ïŒ
component
ïŒãäžããããŸããããçµæã®ãããã«ã¯
component
ãš
foo
2ã€ãæž¡ãããŸããã
宿é¡
ããããåŸ ã£ãŠãã ããïŒ ãã®ã³ãŒãã䜿çšããŠãµã€ãã«ãŒã³ã³ãããäœæããŸããïŒ ç§ã¯ãµã€ãã«ãŒãè¿œå ããæ¹æ³ã瀺ããšèŠåããŸãã...ãããŠä»ãç§ãåŸãç¥èãšã³ãŒãã§ïŒ https : //github.com/dowjones/k8s-webhook-倧èã«å®éšããèªåçã«æ¿å ¥ããããµã€ãã«ãŒã®äœãæ¹ãèŠã€ããŸãã ãšãŠãç°¡åã§ããæ£ããJSONããããæºåããã ãã§ããã¹ãå±éã«è¿œå ã®ã³ã³ãããŒãè¿œå ãããŸãã ããããŒãªãŒã±ã¹ãã¬ãŒã·ã§ã³ïŒ
翻蚳è ããã®PS
ããã°ãã芧ãã ããã
- â ããã§ã¯ãKubernetesã®ããããšã¯äœã§ããïŒ ";
- â Kubernetesã§ã®é«å¯çšæ§ã®æäŸæ¹æ³ â;
- ã Kubernetesã¹ã±ãžã¥ãŒã©ã¯å®éã«ã©ã®ããã«æ©èœããŸããïŒã ";
- ãkubectlã®å®è¡ãéå§ããããšKubernetesã§äœãèµ·ãããŸããïŒã ããŒã1ãšããŒã2 ;
- â Kubernetesã§ã®RBACã®ç解 â;
- ã å°èŠæš¡ãããžã§ã¯ãã§ã®Kubernetesã§ã®çµéš ã ïŒãããªã¬ããŒããKubernetesã®æè¡ããã€ã¹ã®çŽ¹ä»ãå«ãïŒ ã
- ã ãµãŒãã¹ã¡ãã·ã¥ãšã¯äœã§ããããªãå¿ èŠãªã®ã§ããïŒ ãã