{"id":1363,"date":"2021-06-07T04:16:15","date_gmt":"2021-06-07T02:16:15","guid":{"rendered":"https:\/\/wchmurze.cloud\/?p=1363"},"modified":"2021-06-13T22:11:13","modified_gmt":"2021-06-13T20:11:13","slug":"certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3","status":"publish","type":"post","link":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/","title":{"rendered":"Certified Kubernetes Administrator (CKA) krok po kroku &#8211; cz\u0119\u015b\u0107 3"},"content":{"rendered":"<h3><\/h3>\n<h3>Konfiguracja aplikacji na klastrze Kubernetes<\/h3>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>W tej cz\u0119\u015bci pragn\u0119 skupi\u0107 si\u0119 nad konfiguracja naszych aplikacji.\u00a0 Dobr\u0105 i polecana praktyk\u0105 jest oddzielenie kodu aplikacji od jej konfiguracji. Jak to wygl\u0105da po stronie Kubernetes ?<\/p>\n<p>W jaki spos\u00f3b mo\u017cemy przekazywa\u0107 zmienne \u015brodowiskowe ?<\/p>\n<p>Jak podchodzimy do po\u015bwiadcze\u0144 i danych wra\u017cliwych ?<\/p>\n<p>&nbsp;<\/p>\n<p>Mo\u017cemy wstrzykiwa\u0107 konfiguracj\u0119 w postaci zmiennych \u015brodowiskowych jedna zmienna po drugiej. Robili\u015bmy to w jednym z przyk\u0142ad\u00f3w dla obrazu postgresql.<\/p>\n<p>Mo\u017cemy wstrzykn\u0105\u0107 ca\u0142y zbi\u00f3r zmiennych za pomoc\u0105 obiektu <strong>configmap<\/strong>, ale mo\u017cemy te\u017c pod\u0142\u0105czy\u0107 taki obiekt jako plik konfiguracyjny.<\/p>\n<p>Je\u017celi nasze dane konfiguracyjne wymagaj\u0105 wi\u0119kszej ochrony (klucze, certyfikaty, has\u0142a) mamy do czynienia z\u00a0 kolejnym typem obiektu jakim jest <strong>secret<\/strong>.<\/p>\n<p data-selectable-paragraph=\"\">Oba typy obiekt\u00f3w pozwalaj\u0105 na reprezentacj\u0119 konfiguracji w postaci par klucz:warto\u015b\u0107<\/p>\n<p>Nale\u017cy pami\u0119ta\u0107, i\u017c obiekty <strong>configmap<\/strong> nie nadaj\u0105 si\u0119 do sk\u0142adowania du\u017cej liczby danych, takie nale\u017cy przechowywa\u0107 w wolumenach. O tym b\u0119dzie osobny odcinek.<\/p>\n<p>&nbsp;<\/p>\n<p>Zar\u00f3wno obiekty <strong>configmap<\/strong> i <strong>secret<\/strong> mog\u0105 wy\u0107 wykorzystywane przez obiekt <strong>pod<\/strong> w dw\u00f3ch trybach<\/p>\n<ul>\n<li>zmienne \u015brodowiskowe<\/li>\n<li>wolumeny<\/li>\n<\/ul>\n<div class=\"n p\">\n<div class=\"ab ac ae af ag ev ai aj\">\n<p id=\"cbfe\" class=\"kt ku lw kv b fx lo kf kx ga lp ki kz la lq lc ld le lr lg lh li ls lk ll lm dl fv\" data-selectable-paragraph=\"\">Poni\u017cszy rysunek pokazuje mo\u017cliwe schematy.<\/p>\n<\/div>\n<\/div>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-1471\" src=\"https:\/\/wchmurze.cloud\/wp-content\/uploads\/2021\/05\/kubernetes-secret-configmap.png\" alt=\"\" width=\"1360\" height=\"346\" srcset=\"https:\/\/wchmurze.cloud\/wp-content\/uploads\/2021\/05\/kubernetes-secret-configmap.png 1360w, https:\/\/wchmurze.cloud\/wp-content\/uploads\/2021\/05\/kubernetes-secret-configmap-300x76.png 300w, https:\/\/wchmurze.cloud\/wp-content\/uploads\/2021\/05\/kubernetes-secret-configmap-1024x261.png 1024w, https:\/\/wchmurze.cloud\/wp-content\/uploads\/2021\/05\/kubernetes-secret-configmap-768x195.png 768w\" sizes=\"(max-width: 1360px) 100vw, 1360px\" \/><\/p>\n<p>W dzisiejszym odcinku, chcia\u0142bym skupi\u0107 si\u0119 na lewej (czerwonej) stronie i po\u0107wiczy\u0107 wykorzystanie\u00a0 obiekt\u00f3w <strong>configmap<\/strong> i <strong>secret<\/strong> przez zmienne \u015brodowiskowe, z tym, \u017ce dla obiektu <strong>secret<\/strong> zamiast <strong>configMapRef<\/strong> i <strong>configMapKeyRef<\/strong> b\u0119dzie odpowiednio <strong>secretRef<\/strong> i <strong>secretKeyRef<\/strong>.<\/p>\n<p>Montowanie przez wolumen b\u0119dzie opisane w jednym z kolejnych cz\u0119\u015bci przy okazji \u0107wicze\u0144 z wolumenami.<\/p>\n<p>&nbsp;<\/p>\n<p>Wykorzystamy dwa polecenia <strong>kubectl create configmap<\/strong> i <strong>kubectl create secret<\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<p>Rozpoczynamy cz\u0119\u015b\u0107 praktyczn\u0105.<\/p>\n<p>&nbsp;<\/p>\n<p>Wszystkie zasoby w poni\u017cszych zadaniach nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>. Je\u015bli taka nie istnieje na klastrze nale\u017cy j\u0105 utworzy\u0107.<\/p>\n<p>Polecam zawsze dodawanie tej przestrzeni nazw w pliku z\u00a0 manifestem<\/p>\n<p>&nbsp;<\/p>\n<h4>Zadanie pierwsze<\/h4>\n<p>Utw\u00f3rz\u00a0 obiekt pod na nazwie <strong>postgresql-env<\/strong> oparty o obraz<strong> postgres:12.4<\/strong> pracuj\u0105cy na porcie 5432. Dodaj do definicji trzy zmienne \u015brodowiskowe<\/p>\n<div>\n<div>POSTGRES_DB:\u00a0postgresdb<\/div>\n<div>POSTGRES_USER:\u00a0postgresadmin<\/div>\n<div>POSTGRES_PASSWORD:\u00a0admin123<\/div>\n<div><\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/p>\n<p>Przypomnijmy sobie jak to robili\u015bmy w poprzedniej cz\u0119\u015bci.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl run postgresql-env --image=postgres:12.4 --port 5432  \\\r\n  --env=\"POSTGRES_DB=postgresdb\" --env=\"POSTGRES_USER=postgresadmin\" --env=\"POSTGRES_PASSWORD=admin123\" \\\r\n  -o yaml --dry-run=client  &gt; 01.pod.postgresql-env.yaml<\/pre>\n<p>Manifest powinien wygl\u0105da\u0107 tak:<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  creationTimestamp: null\r\n  labels:\r\n    run: postgresql-env\r\n  name: postgresql-env\r\n  namespace: beta\r\nspec:\r\n  containers:\r\n  - env:\r\n    - name: POSTGRES_DB\r\n      value: postgresdb\r\n    - name: POSTGRES_USER\r\n      value: postgresadmin\r\n    - name: POSTGRES_PASSWORD\r\n      value: admin123\r\n    image: postgres:12.4\r\n    name: postgresql-env\r\n    ports:\r\n    - containerPort: 5432\r\n    resources: {}\r\n  dnsPolicy: ClusterFirst\r\n  restartPolicy: Always<\/pre>\n<p>Wida\u0107, \u017ce zmienne \u015brodowiskowe realizowane s\u0105 za pomoc\u0105 listy, kt\u00f3re zawiera w sobie kolejne listy o nazwach <strong>name<\/strong> i <strong>value.<\/strong> Listy takie s\u0105 mapami YAML.<\/p>\n<p>&nbsp;<\/p>\n<h4>Zadanie drugie<\/h4>\n<p>Utw\u00f3rz obiekt typu <strong>configmap<\/strong> o nazwie <strong>postgresql-configmap<\/strong>, kt\u00f3re zawiera nast\u0119puj\u0105ce pary klucz:warto\u015b\u0107<\/p>\n<div>\n<div>POSTGRES_DB:\u00a0postgresdb<\/div>\n<div>POSTGRES_USER:\u00a0postgresadmin<\/div>\n<div>POSTGRES_PASSWORD:\u00a0admin123<\/div>\n<div><\/div>\n<\/div>\n<div>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/div>\n<div><\/div>\n<p>Jak rozpocz\u0105\u0107 prac\u0119?\u00a0 Najlepiej od\u00a0 przejrzenia pomocy<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl create configmap --help<\/pre>\n<p>W zwr\u00f3conej informacji mamy sporo gotowych przyk\u0142ad\u00f3w u\u017cycia<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">Create a configmap based on a file, directory, or specified literal value.\r\n\r\n A single configmap may package one or more key\/value pairs.\r\n\r\n When creating a configmap based on a file, the key will default to the basename of the file, and the value will default\r\nto the file content.  If the basename is an invalid key, you may specify an alternate key.\r\n\r\n When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be\r\npackaged into the configmap.  Any directory entries except regular files are ignored (e.g. subdirectories, symlinks,\r\ndevices, pipes, etc).\r\n\r\nAliases:\r\nconfigmap, cm\r\n\r\nExamples:\r\n  # Create a new configmap named my-config based on folder bar\r\n  kubectl create configmap my-config --from-file=path\/to\/bar\r\n\r\n  # Create a new configmap named my-config with specified keys instead of file basenames on disk\r\n  kubectl create configmap my-config --from-file=key1=\/path\/to\/bar\/file1.txt --from-file=key2=\/path\/to\/bar\/file2.txt\r\n\r\n  # Create a new configmap named my-config with key1=config1 and key2=config2\r\n  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2\r\n\r\n  # Create a new configmap named my-config from the key=value pairs in the file\r\n  kubectl create configmap my-config --from-file=path\/to\/bar\r\n\r\n  # Create a new configmap named my-config from an env file\r\n  kubectl create configmap my-config --from-env-file=path\/to\/bar.env\r\n\r\nOptions:\r\n      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in\r\nthe template. Only applies to golang and jsonpath output formats.\r\n      --append-hash=false: Append a hash of the configmap to its name.\r\n      --dry-run='none': Must be \"none\", \"server\", or \"client\". If client strategy, only print the object that would be\r\nsent, without sending it. If server strategy, submit server-side request without persisting the resource.\r\n      --from-env-file='': Specify the path to a file to read lines of key=val pairs to create a configmap (i.e. a Docker\r\n.env file).\r\n      --from-file=[]: Key file can be specified using its file path, in which case file basename will be used as\r\nconfigmap key, or optionally with a key and file path, in which case the given key will be used.  Specifying a directory\r\nwill iterate each named file in the directory whose basename is a valid configmap key.\r\n      --from-literal=[]: Specify a key and literal value to insert in configmap (i.e. mykey=somevalue)\r\n  -o, --output='': Output format. One of:\r\njson|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.\r\n      --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the\r\nannotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.\r\n      --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The\r\ntemplate format is golang templates [http:\/\/golang.org\/pkg\/text\/template\/#pkg-overview].\r\n      --validate=true: If true, use a schema to validate the input before sending it<\/pre>\n<p>&nbsp;<\/p>\n<p>To co nas interesuje, to przekazanie z linii komend wielokrotnie &#8211;from-literal=KEY=VALUE. W manife\u015bcie YAML zostanie to zamienione na list\u0119 par w postaci map KEY: VALUE.<\/p>\n<div><\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl create configmap postgresql-configmap --from-literal=\"POSTGRES_DB=postgresdb\"  --from-literal=\"POSTGRES_USER=postgresadmin\" \r\n  --from-literal=\"POSTGRES_PASSWORD=admin123\" -n beta \r\n  -o yaml --dry-run=client &gt; 02.configmap.postgresql-configmap.yaml<\/pre>\n<\/div>\n<p>W ten spos\u00f3b otrzymujemy plik 02.configmap.postgresql-configmap.yaml o zawarto\u015bci<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\ndata:\r\n  POSTGRES_DB: postgresdb\r\n  POSTGRES_PASSWORD: admin123\r\n  POSTGRES_USER: postgresadmin\r\nkind: ConfigMap\r\nmetadata:\r\n  creationTimestamp: null\r\n  name: postgresql-configmap\r\n  namespace: beta<\/pre>\n<p>Warto zwr\u00f3ci\u0107 uwag\u0119, i\u017c podstawowa budowa takiego obiektu jest zbli\u017cona do obiektu <strong>pod<\/strong>, z tym, \u017ce zamiast <strong>spec:<\/strong> mamy <strong>data:<\/strong>.<\/p>\n<p>W cz\u0119\u015bci <strong>data:<\/strong> umieszczone s\u0105 pary\u00a0 klucz: warto\u015b\u0107. W poni\u017cszym przyk\u0142adzie<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: ConfigMap\r\nmetadata:\r\n  name: test-configmap\r\ndata:\r\n  KEY: VALUE<\/pre>\n<p>Warto doda\u0107 brakuj\u0105c\u0105 map\u0119 <strong>namespace: beta<\/strong> w obszarze metadata.<\/p>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl apply -f 02.configmap.postgresql-configmap.yaml<\/pre>\n<p>&nbsp;<\/p>\n<h4>Zadanie trzecie<\/h4>\n<p>Utw\u00f3rz\u00a0 obiekt typu <strong>pod<\/strong> o nazwie <strong>postgresql-cm<\/strong> oparty o obraz<strong> postgres:12.4<\/strong> pracuj\u0105cy na porcie <strong>5432<\/strong> i wykorzystuj\u0105cy obiekt <strong>configmap<\/strong> o nazwie <strong>postgresql-configmap<\/strong> z zadania drugiego.<\/p>\n<div><\/div>\n<div>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/div>\n<p>&nbsp;<\/p>\n<p>Na pocz\u0105tku mo\u017cemy skorzysta\u0107 z przygotowanego manifestu w zadaniu pierwszym. Jest to jedna z prostych sztuczke, kt\u00f3re pozwalaj\u0105 zwi\u0119kszy\u0107 tempo rozwi\u0105zywania zada\u0144.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">cp 01.pod.postgresql-env.yaml 03.pod.postgresql-cm.yaml<\/pre>\n<p>Poniewa\u017c chcemy wykorzysta\u0107 wszystkie zmienne zawarte w obiekcie configmap<\/p>\n<p>zamieniamy:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">spec:\r\n  containers:\r\n  - env:\r\n    - name: POSTGRES_DB\r\n      value: postgresdb\r\n    - name: POSTGRES_USER\r\n      value: postgresadmin\r\n    - name: POSTGRES_PASSWORD\r\n      value: admin123<\/pre>\n<p>&nbsp;<\/p>\n<p>na:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">spec:\r\n  containers:\r\n  - envFrom:\r\n    - configMapRef:\r\n        name: postgresql-configmap<\/pre>\n<p>&nbsp;<\/p>\n<p>Pami\u0119taj\u0105c oczywi\u015bcie o zmianie nazwy obiektu. Manifest powinien wygl\u0105da\u0107 tak<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  labels:\r\n    run: postgresql-cm\r\n  name: postgresql-cm\r\n  namespace: beta\r\nspec:\r\n  containers:\r\n  - envFrom:\r\n    - configMapRef:\r\n        name: postgresql-configmap\r\n    image: postgres:12.4\r\n    name: postgresql-cm\r\n    ports:\r\n    - containerPort: 5432\r\n    resources: {}\r\n  dnsPolicy: ClusterFirst\r\n  restartPolicy: Always<\/pre>\n<p>&nbsp;<\/p>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl apply -f 03.pod.postgresql-cm.yaml<\/pre>\n<h4><\/h4>\n<h4>Zadanie czwarte<\/h4>\n<h4><\/h4>\n<p>Utw\u00f3rz obiekt typu <strong>configmap<\/strong> o nazwie <strong>postgresql-configmap-nopass<\/strong>, kt\u00f3re zawiera nast\u0119puj\u0105ce pary klucz:warto\u015b\u0107<\/p>\n<div>\n<div><\/div>\n<div>POSTGRES_DB:\u00a0postgresdb<\/div>\n<div>POSTGRES_USER:\u00a0postgresadmin<\/div>\n<div><\/div>\n<div>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/div>\n<div>Mo\u017cna wygenerowa\u0107 manifest w ten spos\u00f3b, wykorzystuj\u0105c zadanie drugie<\/div>\n<\/div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl create configmap postgresql-configmap-nopass \r\n  --from-literal=\"POSTGRES_DB=postgresdb\" \r\n  --from-literal=POSTGRES_USER=postgresadmin -n beta\r\n  -o yaml --dry-run=client &gt; 04.configmap.postgresql-configmap-nopass.yaml<\/pre>\n<p>Ale mo\u017cna te\u017c skopiowa\u0107 wygenerowany w zadaniu dwa manifest<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">cp 02.configmap.postgresql-configmap.yaml 04.configmap.postgresql-configmap-nopass.yaml<\/pre>\n<p>Pami\u0119tajmy o usuni\u0119ciu zb\u0119dnej pary zawieraj\u0105cej has\u0142o do bazy i zmianie nazwy obiektu <strong>configmap<\/strong>. Bez zmiany nazwy mo\u017cemy sobie nadpisa\u0107 obiekt na klastrze, ale poniewa\u017c trzymamy je wszystkie w postaci plik\u00f3w, \u0142atwo mo\u017cna taka pomy\u0142k\u0119 naprawi\u0107.<\/p>\n<p>&nbsp;<\/p>\n<p>Niezale\u017cnie od rozwi\u0105zania powinni\u015bmy otrzyma\u0107 plik 04.configmap.postgresql-configmap-nopass.yaml o\u00a0 poni\u017cszej zawarto\u015bci<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\ndata:\r\n  POSTGRES_DB: postgresdb\r\n  POSTGRES_USER: postgresadmin\r\nkind: ConfigMap\r\nmetadata:\r\n  creationTimestamp: null\r\n  name: postgresql-configmap-nopass\r\n  namespace: beta<\/pre>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">kubectl apply -f 04.configmap.postgresql-configmap-nopass.yaml<\/pre>\n<p>&nbsp;<\/p>\n<h4>Zadanie pi\u0105te<\/h4>\n<p>Utw\u00f3rz obiekt typu <strong>secret <\/strong>o nazwie <strong>postgresql-secret<\/strong>, kt\u00f3re zawiera nast\u0119puj\u0105ce pary klucz:warto\u015b\u0107<\/p>\n<div>\n<div>POSTGRES_PASSWORD: admin123<\/div>\n<div><\/div>\n<div>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl create secret generic postgresql-secret  -n beta --from-literal=\"POSTGRES_PASSWORD=admin123\"  -o yaml --dry-run=client &gt; 05.secret.postgresql-secret.yaml<\/pre>\n<p>Zasadnicza sk\u0142adnia jest identyczna z t\u0105 wykorzystuj\u0105c\u0105 obiekt configmap, z tym \u017ce nale\u017cy poda\u0107 przed nazwa obiekty jego typ. W naszym przypadku jest to typ og\u00f3lny (generic)<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl create secret --help<\/pre>\n<p>Mamy trzy mo\u017cliwo\u015bci do wyboru<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">Create a secret using specified subcommand.\r\n\r\nAvailable Commands:\r\n  docker-registry Create a secret for use with a Docker registry\r\n  generic         Create a secret from a local file, directory or literal value\r\n  tls             Create a TLS secret\r\n\r\nUsage:\r\n  kubectl create secret [flags] [options]<\/pre>\n<p>Druga rzecz, na kt\u00f3r\u0105 nale\u017cy zwr\u00f3ci\u0107 uwag\u0119, to zakodowan\u0105 warto\u015b\u0107 i niezakodowany klucz.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\ndata:\r\n  POSTGRES_PASSWORD: YWRtaW4xMjM=\r\nkind: Secret\r\nmetadata:\r\n  creationTimestamp: null\r\n  name: postgresql-secret\r\n  namespace: beta<\/pre>\n<p>W jaki spos\u00f3b mo\u017cna odkodowa\u0107 to has\u0142o ?<\/p>\n<p>Bardzo prostu, gdy\u017c wykorzystany tu zosta\u0142 base64.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">echo -n admin123 | base64<\/pre>\n<p>zwr\u00f3ci nam warto\u015b\u0107 <strong>YWRtaW4xMjM=<\/strong><\/p>\n<p>Odwrotnie polecenie<\/p>\n<pre><code class=\"language-shell\" data-lang=\"shell\">echo -n YWRtaW4xMjM= | base64 --decode<\/code><\/pre>\n<p>zwraca nam warto\u015b\u0107 <strong>admin123<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl apply -f 05.secret.postgresql-secret.yaml<\/pre>\n<p>W tym miejscu warto zweryfikowa\u0107, czy da si\u0119 odkodowa\u0107 has\u0142o bez wykorzystywania base64 &#8211;decode?<\/p>\n<p>Dla polecenia<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl describe secret postgresql-secret -n beta<\/pre>\n<p>zwracany jest<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">Name:         postgresql-secret\r\nNamespace:    beta\r\nLabels:       \r\nAnnotations:  \r\n\r\nType:  Opaque\r\n\r\nData\r\n====\r\nPOSTGRES_PASSWORD:  8 bytes<\/pre>\n<p>Has\u0142a nie wida\u0107, nawet w postaci zakodowanej<\/p>\n<p>&nbsp;<\/p>\n<p>Mo\u017cna spr\u00f3bowa\u0107 pobra\u0107 posta\u0107 w wersji YAML (-o yaml)<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl get secret postgresql-secret -n beta -o yaml<\/pre>\n<p>W zwr\u00f3conej postaci widzimy has\u0142o zakodowane.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">kubectl get secret postgresql-secret -n beta -o yaml\r\napiVersion: v1\r\ndata:\r\n  POSTGRES_PASSWORD: YWRtaW4xMjM=\r\nkind: Secret\r\nmetadata:\r\n  name: postgresql-secret\r\n  namespace: beta\r\ntype: Opaque<\/pre>\n<p>W powy\u017cszym manife\u015bcie obiektu wdro\u017conego na klastrze pozby\u0142em si\u0119 cz\u0119\u015bci doklejanych przez klaster. To dobre \u0107wiczenie, dla os\u00f3b, kt\u00f3re chc\u0105 ogl\u0105da\u0107 posta\u0107 YAML nie z kodu \u017ar\u00f3d\u0142owego, ale z tego co jest wdro\u017cone. ManagedFields b\u0119d\u0105 si\u0119 wam \u015bni\u0142y nie raz (!).<\/p>\n<p>Istnieje te\u017c oprocz <strong>kubectl describe secret<\/strong>, czy <strong>kubectl get secret -o yaml<\/strong> mo\u017cliwo\u015b\u0107 skorzystania z <strong>jsonpath<\/strong>, czyli takiego sql dla json.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl get secret postgresql-secret -n beta -o jsonpath='{.data}'<\/pre>\n<p>zwr\u00f3cony rezultat<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\"POSTGRES_PASSWORD\":\"YWRtaW4xMjM=\"}<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl get secret postgresql-secret -n beta -o jsonpath='{.data.POSTGRES_PASSWORD}'<\/pre>\n<p>&nbsp;<\/p>\n<p>zwr\u00f3cony rezultat<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">YWRtaW4xMjM=<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl get secret postgresql-secret -n beta -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 --decode<\/pre>\n<p>zwr\u00f3cony rezultat<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">admin123<\/pre>\n<p>Specyfikacj\u0119 mo\u017cna przejrze\u0107 tutaj<\/p>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/jsonpath\/\" target=\"_blank\" rel=\"noopener\">https:\/\/kubernetes.io\/docs\/reference\/kubectl\/jsonpath\/<\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Zadanie sz\u00f3ste<\/h4>\n<p>&nbsp;<\/p>\n<p>Utw\u00f3rz\u00a0 obiekt typu <strong>pod<\/strong> o nazwie <strong>postgresql-cm-secret<\/strong> oparty o obraz<strong> postgres:12.4<\/strong> pracuj\u0105cy na porcie 5432 i wykorzystuj\u0105cy obiekt <strong>configmap<\/strong> o nazwie <strong>postgresql-configmap-nopass<\/strong> z zadania czwartego i obiekt secret o nazwie <strong>postgresql-secret<\/strong> z zadania pi\u0105tego.<\/p>\n<p>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/p>\n<p>Na pocz\u0105tku mo\u017cemy skopiowa\u0107 obiekt pod z zadania drugiego. Podczas generowania na egzaminie kolejnych plik\u00f3w kopiowanie z inneych zada\u0144 jest cz\u0119st\u0105 praktyk\u0105.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">cp  02.pod.postgresql-cm.yaml 06.pod.postgresql-cm-secret.yaml<\/pre>\n<p>W manife\u015bcie nale\u017cy doda\u0107 jako \u017ar\u00f3d\u0142o zmiennych kolejny element listy obiekt <strong>secret<\/strong> o nazwie <strong>postgresql-secret<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">- envFrom: \r\n  - secretRef: \r\n      name: postgresql-secret<\/pre>\n<p>Jak wida\u0107 zamiast <strong>configMapRef<\/strong> mamy <strong>secretRef<\/strong>.<\/p>\n<p>Nasz plik z namifestem powinien wygl\u0105da\u0107 tak<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  labels:\r\n    run: postgresql-cm-secret\r\n  name: postgresql-cm-secret\r\n  namespace: beta\r\nspec:\r\n  containers:\r\n  - envFrom:\r\n    - configMapRef:\r\n        name: postgresql-configmap-nopass\r\n    - secretRef:\r\n        name: postgresql-secret\r\n    image: postgres:12.4\r\n    name: postgresql-cm-secret\r\n    ports:\r\n    - containerPort: 5432\r\n    resources: {}\r\n  dnsPolicy: ClusterFirst\r\n  restartPolicy: Always<\/pre>\n<p>&nbsp;<\/p>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl apply -f 06.pod.postgresql-cm-secret.yaml<\/pre>\n<h4>Zadanie si\u00f3dme<\/h4>\n<p>&nbsp;<\/p>\n<p>Utw\u00f3rz\u00a0 obiekt typu <strong>pod<\/strong> o nazwie <strong>postgresql-cm-nopass-secret<\/strong> oparty o obraz<strong> postgres:12.4<\/strong> pracuj\u0105cy na porcie <strong>5432<\/strong> i wykorzystuj\u0105cy obiekt <strong>configmap<\/strong> o nazwie <strong>postgresql-configmap<\/strong> z zadania drugiego i obiekt secret o nazwie <strong>postgresql-secret<\/strong> z zadania pi\u0105tego.<\/p>\n<p>Z obiektu configmap wykorzystaj tylko dwie zmienne<\/p>\n<div>POSTGRES_DB:\u00a0postgresdb<\/div>\n<div>POSTGRES_USER:\u00a0postgresadmin<\/div>\n<div><\/div>\n<p>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/p>\n<p>Poniewa\u017c zadanie to wygl\u0105da bardzo podobnie do zadania sz\u00f3stego zacznijmy prac\u0119 od sklonowania pliku manifest<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">cp 06.pod.postgresql-cm-secret.yaml 07.pod.postgresql-cm-nopass-secret.yaml<\/pre>\n<p>W tak przygotowanym pliku 07.pod.postgresql-cm-nopass-secret.yaml nale\u017cy zmieni\u0107 jak zwykle nazw\u0119 obiektu<\/p>\n<p>oraz zamieni\u0107<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">- envFrom: \r\n  - configMapRef: \r\n      name: postgresql-configmap-nopass<\/pre>\n<p>na:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\"> - env:\r\n\u00a0\u00a0 - name: POSTGRES_DB\r\n\u00a0\u00a0\u00a0\u00a0 valueFrom:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0  configMapKeyRef:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  name: postgresql-configmap\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: POSTGRES_DB\r\n\u00a0\u00a0\u00a0- name: POSTGRES_USER\r\n\u00a0\u00a0\u00a0\u00a0\u00a0valueFrom:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0  configMapKeyRef:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  name: postgresql-configmap\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: POSTGRES_USER<\/pre>\n<p>&nbsp;<\/p>\n<p>Nasz docelowy manifest powinien wygl\u0105da\u0107 tak:<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  labels:\r\n    run: postgresql-cm-nopass-secret\r\n  name: postgresql-cm-nopass-secret\r\n  namespace: beta\r\nspec:\r\n  containers:\r\n  - envFrom:\r\n    - secretRef:\r\n        name: postgresql-secret\r\n    env:\r\n    - name: POSTGRES_DB\r\n      valueFrom:\r\n        configMapKeyRef:\r\n          name: postgresql-configmap\r\n          key: POSTGRES_DB\r\n    - name: POSTGRES_USER\r\n      valueFrom:\r\n        configMapKeyRef:\r\n          name: postgresql-configmap\r\n          key: POSTGRES_USER\r\n\r\n    image: postgres:12.4\r\n    name: postgresql-cm-secret\r\n    ports:\r\n    - containerPort: 5432\r\n    resources: {}\r\n  dnsPolicy: ClusterFirst\r\n  restartPolicy: Always<\/pre>\n<p>Uwa\u017cni zauwa\u017c\u0105 brak <strong>&#8211;<\/strong> przed env. Jest to kolejny element listy (envFrom,env,image,name,ports&#8230;.). Tylko element pierwszy powinien byc tak oznaczony.<\/p>\n<p>Czy mo\u017cna np. zamieni\u0107 envFrom z env ? Mo\u017cna. Taki manifest wygl\u0105da wtedy tak.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  labels:\r\n    run: postgresql-cm-nopass-secret\r\n  name: postgresql-cm-nopass-secret\r\n  namespace: beta\r\nspec:\r\n  containers:\r\n  - env:\r\n    - name: POSTGRES_DB\r\n      valueFrom:\r\n        configMapKeyRef:\r\n          name: postgresql-configmap\r\n          key: POSTGRES_DB\r\n    - name: POSTGRES_USER\r\n      valueFrom:\r\n        configMapKeyRef:\r\n          name: postgresql-configmap\r\n          key: POSTGRES_USER\r\n    envFrom:\r\n    - secretRef:\r\n        name: postgresql-secret\r\n    image: postgres:12.4\r\n    name: postgresql-cm-secret\r\n    ports:\r\n    - containerPort: 5432\r\n    resources: {}\r\n  dnsPolicy: ClusterFirst\r\n  restartPolicy: Always<\/pre>\n<p>&nbsp;<\/p>\n<p>Inne elementy listy rownie\u017c mog\u0105 mie\u0107 zamienion\u0105 kolejno\u015b\u0107. Jest to jedna z cech manifest\u00f3w YAML dla Kubernetes, kt\u00f3ra na pocz\u0105tku sprawia\u0142a mi trudno\u015bci. Dobrze jest przyj\u0105\u0107 konwencj\u0119, w kt\u00f3rej na przyklad pierwszym elementem listy jest <strong>name<\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl apply -f 07.pod.postgresql-cm-nopass-secret.yaml<\/pre>\n<h4>Zadanie \u00f3sme<\/h4>\n<p>&nbsp;<\/p>\n<p>Utw\u00f3rz obiekt typu service o nazwie <strong>postgresql-webservice<\/strong>, kt\u00f3ry wystawi obiekt pod o nazwie <strong>postgresql-cm-secret<\/strong> z zadania sz\u00f3stego. Rodzaj serwisu to ClusterIP.<\/p>\n<div>\n<div><\/div>\n<div>Obiekt nale\u017cy umie\u015bci\u0107 w przestrzeni nazw <strong>beta<\/strong>.<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-linenumbers=\"false\">kubectl expose pod\/postgresql-cm-secret --name=postgresql-webservice -n beta-o yaml --dry-run=client &gt; 08.service.postgresql-webservice.yaml<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  creationTimestamp: null\r\n  labels:\r\n    run: postgresql-cm-secret\r\n  name: postgresql-webservice\r\n  namespace: beta\r\nspec:\r\n  ports:\r\n  - port: 5432\r\n    protocol: TCP\r\n    targetPort: 5432\r\n  selector:\r\n    run: postgresql-cm-secret\r\nstatus:\r\n  loadBalancer: {}<\/pre>\n<p>&nbsp;<\/p>\n<p>Tak przygotowany manifest mo\u017cemy wdro\u017cy\u0107 na klaster<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-linenumbers=\"false\">kubectl apply -f 08.service.postgresql-webservice.yaml<\/pre>\n<p>&nbsp;<\/p>\n<p>Na tym etapie zarysowali\u015bmy jedynie mo\u017cliwo\u015bci wstrzykiwania konfiguracji za pomoc\u0105 zmiennych \u015brodowiskowym. W dalszych cz\u0119sciach postaram si\u0119 ten temat jeszcze rozszerzy\u0107.<\/p>\n<p>&nbsp;<\/p>\n<p>Dla tych, kt\u00f3rzy zd\u0105\u017cyli si\u0119 pogub\u0107 ma\u0142e podsumowanie tego co znajduje si\u0119 w manife\u015bcie ka\u017cdego obiektu umieszczanego w przestrzeni nazw.<\/p>\n<p>Interesuje nas cz\u0119\u015b\u0107 <strong>metadata<\/strong>:<\/p>\n<p>G\u0142\u00f3wne atrybuty, z kt\u00f3rymi si\u0119 spotkamy to<\/p>\n<ul>\n<li>name<\/li>\n<li>nemaspace<\/li>\n<li>labels<\/li>\n<li>annotations<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Przyk\u0142adowy kawa\u0142ek menifestu<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: v1\r\nkind: ConfigMap\r\n# metadata start\r\nmetadata: \r\n  name: pod-config\r\n  namespace: epsilon\r\n  labels:\r\n    tier: frontend\r\n    env: dev\r\n    version: 1.8\r\n   annotations:\r\n     controlled-by: me\r\n# metadata end   \r\n\r\n<\/pre>\n<p>Nazwa (<strong>name<\/strong>) jest <strong>obligatoryjnym<\/strong> atrybutem, kt\u00f3ry musi by\u0107 ustawiony podczas tworzenia, czy modyfikacji takich obiekt\u00f3w jak Pod,Deployment, ConfigMap, itp&#8230; Nazwa jest dla danej przestrzeni nazw unikalna. Nie uda si\u0119 wdro\u017cy\u0107 dw\u00f3ch obiekt\u00f3w pod o tej samej nazwie w tej samej przestrzeni.<\/p>\n<p>Ka\u017cdy obiekt, kt\u00f3rego zasi\u0119g jest w zakresie przestrzeni nazw, mo\u017ce mie\u0107 dodany atrybut <strong>namespace<\/strong>. Je\u015bli nie zostanie podany domy\u015bln\u0105 warto\u015bcia jest przestrze\u0144 nazw <strong>default<\/strong>.<\/p>\n<p>Etykliety (<strong>labels<\/strong>) s\u0105 parami klucz:warto\u015b\u0107. S\u0105 one wykorzystywane do \u0142atywej identyfikacji zasobu, mog\u0105 si\u0119 zmienia\u0107 w czasie. Ka\u017cdy klucz jest unikalny w ramach obiektu.<\/p>\n<p>Adnotacje (<strong>annotations<\/strong>) pozwalaj\u0105 na dodanie do obiektu informacji, kt\u00f3re nie s\u0142u\u017c\u0105 do identyfikacji, ale na przyk\u0142ad do dodatkowej konfiguracji. Jest to powszechnie stosowane przy obiekcie typu <strong>ingress<\/strong><\/p>\n<p>&nbsp;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">apiVersion: networking.k8s.io\/v1beta1\r\nkind: Ingress\r\nmetadata:\r\n  name: basic-ingress\r\n  annotations:\r\n    kubernetes.io\/ingress.global-static-ip-name: \"web-static-ip\"\r\nspec:\r\n  backend:\r\n    serviceName: web\r\n    servicePort: 8080<\/pre>\n<p>&nbsp;<\/p>\n<p>I to by by\u0142o tyle na dzi\u015b.<\/p>\n<p>&nbsp;<\/p>\n<p>Poprzednie cz\u0119\u015bci:<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/wchmurze.cloud\/index.php\/2021\/05\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-1\/\" target=\"_blank\" rel=\"noopener\">Certified Kubernetes Administrator (CKA) krok po kroku \u2013 cz\u0119\u015b\u0107 1<\/a><\/p>\n<p><a href=\"https:\/\/wchmurze.cloud\/index.php\/2021\/05\/24\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-2\/\" target=\"_blank\" rel=\"noopener\">Certified Kubernetes Administrator (CKA) krok po kroku \u2013 cz\u0119\u015b\u0107 2<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Nast\u0119pne cz\u0119\u015bci<\/p>\n<p><a href=\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/13\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-4\/\" target=\"_blank\" rel=\"noopener\">Certified Kubernetes Administrator (CKA) krok po kroku \u2013 cz\u0119\u015b\u0107 4<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Literatura:<\/p>\n<p><a href=\"https:\/\/www.katacoda.com\/djkormo\/scenarios\/kubernetes-cka-part2\" target=\"_blank\" rel=\"noopener\">https:\/\/www.katacoda.com\/djkormo\/scenarios\/kubernetes-cka-part2<\/a><\/p>\n<p><a href=\"https:\/\/itnext.io\/kubernetes-explained-deep-enough-configuration-cd4a9d1d8dcd\" target=\"_blank\" rel=\"noopener\">https:\/\/itnext.io\/kubernetes-explained-deep-enough-configuration-cd4a9d1d8dcd<\/a><\/p>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\" target=\"_blank\" rel=\"noopener\">https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/<\/a><\/p>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-pod-configmap\/\" target=\"_blank\" rel=\"noopener\">https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-pod-configmap\/<\/a><\/p>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/inject-data-application\/distribute-credentials-secure\/\" target=\"_blank\" rel=\"noopener\">https:\/\/kubernetes.io\/docs\/tasks\/inject-data-application\/distribute-credentials-secure\/<\/a><\/p>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/jsonpath\/\" target=\"_blank\" rel=\"noopener\">https:\/\/kubernetes.io\/docs\/reference\/kubectl\/jsonpath\/<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/kubernetes\/community\/blob\/master\/contributors\/design-proposals\/architecture\/identifiers.md\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/kubernetes\/community\/blob\/master\/contributors\/design-proposals\/architecture\/identifiers.md<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Konfiguracja aplikacji na klastrze Kubernetes &nbsp; &nbsp; W tej cz\u0119\u015bci pragn\u0119 skupi\u0107 si\u0119 nad konfiguracja naszych aplikacji.\u00a0 Dobr\u0105 i polecana praktyk\u0105 jest oddzielenie kodu aplikacji od jej konfiguracji. Jak to wygl\u0105da po stronie Kubernetes ? W jaki spos\u00f3b mo\u017cemy przekazywa\u0107 &hellip; <a href=\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\">Continued<\/a><\/p>\n","protected":false},"author":1,"featured_media":1060,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[22,27,23,26],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.13 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Certified Kubernetes Administrator (CKA) krok po kroku - cz\u0119\u015b\u0107 3 - W chmurze o chmurze i nie tylko<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\" \/>\n<meta property=\"og:locale\" content=\"pl_PL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Certified Kubernetes Administrator (CKA) krok po kroku - cz\u0119\u015b\u0107 3 - W chmurze o chmurze i nie tylko\" \/>\n<meta property=\"og:description\" content=\"Konfiguracja aplikacji na klastrze Kubernetes &nbsp; &nbsp; W tej cz\u0119\u015bci pragn\u0119 skupi\u0107 si\u0119 nad konfiguracja naszych aplikacji.\u00a0 Dobr\u0105 i polecana praktyk\u0105 jest oddzielenie kodu aplikacji od jej konfiguracji. Jak to wygl\u0105da po stronie Kubernetes ? W jaki spos\u00f3b mo\u017cemy przekazywa\u0107 &hellip; Continued\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\" \/>\n<meta property=\"og:site_name\" content=\"W chmurze o chmurze i nie tylko\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-07T02:16:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-06-13T20:11:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wchmurze.cloud\/wp-content\/uploads\/2019\/08\/Kubernetes_New.png\" \/>\n\t<meta property=\"og:image:width\" content=\"730\" \/>\n\t<meta property=\"og:image:height\" content=\"389\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"djkormo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Napisane przez\" \/>\n\t<meta name=\"twitter:data1\" content=\"djkormo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Szacowany czas czytania\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minut\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\"},\"author\":{\"name\":\"djkormo\",\"@id\":\"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323\"},\"headline\":\"Certified Kubernetes Administrator (CKA) krok po kroku &#8211; cz\u0119\u015b\u0107 3\",\"datePublished\":\"2021-06-07T02:16:15+00:00\",\"dateModified\":\"2021-06-13T20:11:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\"},\"wordCount\":1738,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323\"},\"articleSection\":[\"Certyfikacja\",\"CKA\",\"konteneryzacja\",\"Kubernetes\"],\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\",\"url\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\",\"name\":\"Certified Kubernetes Administrator (CKA) krok po kroku - cz\u0119\u015b\u0107 3 - W chmurze o chmurze i nie tylko\",\"isPartOf\":{\"@id\":\"https:\/\/wchmurze.cloud\/#website\"},\"datePublished\":\"2021-06-07T02:16:15+00:00\",\"dateModified\":\"2021-06-13T20:11:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#breadcrumb\"},\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\u0142\u00f3wna\",\"item\":\"https:\/\/wchmurze.cloud\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Certified Kubernetes Administrator (CKA) krok po kroku &#8211; cz\u0119\u015b\u0107 3\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/wchmurze.cloud\/#website\",\"url\":\"https:\/\/wchmurze.cloud\/\",\"name\":\"W chmurze o chmurze i nie tylko\",\"description\":\"W chmurze o chmurze i nie tylko\",\"publisher\":{\"@id\":\"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/wchmurze.cloud\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pl-PL\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323\",\"name\":\"djkormo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/wchmurze.cloud\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/14a901b808871fa98086ae259c45d646?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/14a901b808871fa98086ae259c45d646?s=96&d=mm&r=g\",\"caption\":\"djkormo\"},\"logo\":{\"@id\":\"https:\/\/wchmurze.cloud\/#\/schema\/person\/image\/\"},\"url\":\"https:\/\/wchmurze.cloud\/index.php\/author\/djkormo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Certified Kubernetes Administrator (CKA) krok po kroku - cz\u0119\u015b\u0107 3 - W chmurze o chmurze i nie tylko","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/","og_locale":"pl_PL","og_type":"article","og_title":"Certified Kubernetes Administrator (CKA) krok po kroku - cz\u0119\u015b\u0107 3 - W chmurze o chmurze i nie tylko","og_description":"Konfiguracja aplikacji na klastrze Kubernetes &nbsp; &nbsp; W tej cz\u0119\u015bci pragn\u0119 skupi\u0107 si\u0119 nad konfiguracja naszych aplikacji.\u00a0 Dobr\u0105 i polecana praktyk\u0105 jest oddzielenie kodu aplikacji od jej konfiguracji. Jak to wygl\u0105da po stronie Kubernetes ? W jaki spos\u00f3b mo\u017cemy przekazywa\u0107 &hellip; Continued","og_url":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/","og_site_name":"W chmurze o chmurze i nie tylko","article_published_time":"2021-06-07T02:16:15+00:00","article_modified_time":"2021-06-13T20:11:13+00:00","og_image":[{"width":730,"height":389,"url":"https:\/\/wchmurze.cloud\/wp-content\/uploads\/2019\/08\/Kubernetes_New.png","type":"image\/png"}],"author":"djkormo","twitter_card":"summary_large_image","twitter_misc":{"Napisane przez":"djkormo","Szacowany czas czytania":"11 minut"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#article","isPartOf":{"@id":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/"},"author":{"name":"djkormo","@id":"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323"},"headline":"Certified Kubernetes Administrator (CKA) krok po kroku &#8211; cz\u0119\u015b\u0107 3","datePublished":"2021-06-07T02:16:15+00:00","dateModified":"2021-06-13T20:11:13+00:00","mainEntityOfPage":{"@id":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/"},"wordCount":1738,"commentCount":0,"publisher":{"@id":"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323"},"articleSection":["Certyfikacja","CKA","konteneryzacja","Kubernetes"],"inLanguage":"pl-PL","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/","url":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/","name":"Certified Kubernetes Administrator (CKA) krok po kroku - cz\u0119\u015b\u0107 3 - W chmurze o chmurze i nie tylko","isPartOf":{"@id":"https:\/\/wchmurze.cloud\/#website"},"datePublished":"2021-06-07T02:16:15+00:00","dateModified":"2021-06-13T20:11:13+00:00","breadcrumb":{"@id":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#breadcrumb"},"inLanguage":"pl-PL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wchmurze.cloud\/index.php\/2021\/06\/07\/certified-kubernetes-administrator-cka-krok-po-kroku-czesc-3\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/wchmurze.cloud\/"},{"@type":"ListItem","position":2,"name":"Certified Kubernetes Administrator (CKA) krok po kroku &#8211; cz\u0119\u015b\u0107 3"}]},{"@type":"WebSite","@id":"https:\/\/wchmurze.cloud\/#website","url":"https:\/\/wchmurze.cloud\/","name":"W chmurze o chmurze i nie tylko","description":"W chmurze o chmurze i nie tylko","publisher":{"@id":"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wchmurze.cloud\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pl-PL"},{"@type":["Person","Organization"],"@id":"https:\/\/wchmurze.cloud\/#\/schema\/person\/9832cc6f86f99f541d983d2b8d60f323","name":"djkormo","image":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/wchmurze.cloud\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/14a901b808871fa98086ae259c45d646?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/14a901b808871fa98086ae259c45d646?s=96&d=mm&r=g","caption":"djkormo"},"logo":{"@id":"https:\/\/wchmurze.cloud\/#\/schema\/person\/image\/"},"url":"https:\/\/wchmurze.cloud\/index.php\/author\/djkormo\/"}]}},"_links":{"self":[{"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/posts\/1363"}],"collection":[{"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/comments?post=1363"}],"version-history":[{"count":29,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/posts\/1363\/revisions"}],"predecessor-version":[{"id":1522,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/posts\/1363\/revisions\/1522"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/media\/1060"}],"wp:attachment":[{"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/media?parent=1363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/categories?post=1363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wchmurze.cloud\/index.php\/wp-json\/wp\/v2\/tags?post=1363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}