<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Roger Oliveira</title>
    <description>The latest articles on DEV Community by Roger Oliveira (@rogeroliveira86).</description>
    <link>https://dev.to/rogeroliveira86</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4061419%2F1d07b738-ee1c-4904-ba4e-aa47378b3e32.png</url>
      <title>DEV Community: Roger Oliveira</title>
      <link>https://dev.to/rogeroliveira86</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rogeroliveira86"/>
    <language>en</language>
    <item>
      <title>Linux from Zero #4 — Users, Groups and Permissions for Platform Engineers</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Wed, 02 Sep 2026 13:48:36 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/linux-from-zero-4-users-groups-and-permissions-for-platform-engineers-150k</link>
      <guid>https://dev.to/rogeroliveira86/linux-from-zero-4-users-groups-and-permissions-for-platform-engineers-150k</guid>
      <description>&lt;p&gt;ou deploy a pod. It crashloops. You check the logs and find the most generic error in computing:&lt;/p&gt;

&lt;p&gt;Permission denied&lt;/p&gt;

&lt;p&gt;Then comes the ritual: someone suggests chmod 777, someone suggests running as root, the pod comes up, everyone moves on. It worked. But nobody knows why — and three months later the same error shows up somewhere else.&lt;/p&gt;

&lt;p&gt;Linux permissions are among the easiest topics to explain and the most poorly learned in our field. Not because they're hard, but because almost everyone memorized 755 and 644 without ever understanding where those numbers come from.&lt;/p&gt;

&lt;p&gt;Let's fix that.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Linux doesn't know your name — it knows your number&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the idea that unlocks everything else.&lt;/p&gt;

&lt;p&gt;When ls -l shows roger, that's decoration. The kernel has no idea what "roger" is. It knows a number: the UID. Same for groups — the GID.&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
$ id&lt;br&gt;
uid=1000(roger) gid=1000(roger) groups=1000(roger),27(sudo),999(docker)&lt;/p&gt;

&lt;p&gt;The number-to-name mapping lives in plain text files:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
$ grep roger /etc/passwd&lt;br&gt;
roger❌1000:1000:Roger Oliveira:/home/roger:/bin/bash&lt;/p&gt;

&lt;h1&gt;
  
  
  name:password:UID:GID:comment:home:shell
&lt;/h1&gt;

&lt;p&gt;File    Holds&lt;br&gt;
/etc/passwd user, UID, primary GID, home, shell&lt;br&gt;
/etc/group  groups and their members&lt;br&gt;
/etc/shadow password hashes (root-only)&lt;/p&gt;

&lt;p&gt;Why this matters for platform work: a container has its own /etc/passwd, but shares the kernel — and therefore the UIDs — with the host. If the container process runs as UID 1000 and the file on the volume belongs to UID 2000, no username on earth will fix it. It's number against number.&lt;/p&gt;

&lt;p&gt;That's why chmod 777 "works": it gives up on the check instead of resolving the mismatch.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The three digits, finally explained&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every file has one owner (a UID) and one group (a GID). Permissions are defined for three classes:&lt;/p&gt;

&lt;p&gt;Class   Who&lt;br&gt;
user (u)    the file owner&lt;br&gt;
group (g)   members of the file's group&lt;br&gt;
others (o)  everyone else&lt;/p&gt;

&lt;p&gt;And three permissions per class:&lt;/p&gt;

&lt;p&gt;Letter  Value   On a file   On a directory&lt;br&gt;
r   4   read contents   list names inside&lt;br&gt;
w   2   modify contents create/delete/rename inside&lt;br&gt;
x   1   execute traverse&lt;br&gt;
-rw-r--r--  →  6 4 4  →  644&lt;br&gt;
 │ │  │  └── others: r--&lt;br&gt;
 │ │  └───── group:  r--&lt;br&gt;
 │ └──────── user:   rw-&lt;br&gt;
 └────────── type (- file, d directory, l link)&lt;/p&gt;

&lt;p&gt;No memorization needed: add 4+2+1 within each block of three.&lt;/p&gt;

&lt;p&gt;Common patterns:&lt;/p&gt;

&lt;p&gt;644 — owner writes, everyone reads. Config files.&lt;br&gt;
600 — owner only. Private keys and secrets.&lt;br&gt;
755 — owner writes, everyone executes. Binaries and directories.&lt;br&gt;
777 — everyone does everything. This isn't a permission, it's the absence of one.&lt;br&gt;
The directory x trap&lt;/p&gt;

&lt;p&gt;This one catches good engineers. On a directory, x doesn't mean "execute" — it means you may pass through.&lt;/p&gt;

&lt;p&gt;A directory with r but no x lets you see filenames but open none of them. A directory with x but no r lets you open a file if you know its exact name, but not list the contents.&lt;/p&gt;

&lt;p&gt;And it must hold across the entire path. If /data has no x for you, it doesn't matter that /data/app/config.yml is 777 — you'll never reach it.&lt;/p&gt;

&lt;p&gt;The command that solves this in five seconds:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
$ namei -l /data/app/config.yml&lt;br&gt;
f: /data/app/config.yml&lt;br&gt;
 drwxr-xr-x root root  /&lt;br&gt;
 drwxr-x--- root infra data      ← here&lt;br&gt;
 drwxr-xr-x app  app   app&lt;br&gt;
 -rw-r--r-- app  app   config.yml&lt;/p&gt;

&lt;p&gt;Found it. data only allows entry for root and members of infra.&lt;/p&gt;

&lt;p&gt;namei -l should be the first command of any permission investigation. It walks the whole path, layer by layer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Changing ownership and mode
bash
chmod 640 secret.env          # octal
chmod u+x deploy.sh           # symbolic
chmod g-w app.conf
chmod o= secret.env           # zero out "others"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;chown app:platform config.yml&lt;br&gt;
chown -R app:platform /opt/app&lt;br&gt;
chgrp platform config.yml&lt;/p&gt;

&lt;p&gt;Recursion without collateral damage — capital X applies execute only to directories:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
chmod -R u=rwX,go=rX /opt/app&lt;/p&gt;

&lt;p&gt;chmod -R 755 would mark every data file as executable. Don't.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The three bits nobody explains
Bit Octal   Shows as    Effect
setuid  4000    -rwsr-xr-x  runs with the file owner's privileges
setgid  2000    drwxr-sr-x  new files inherit the directory's group
sticky  1000    drwxrwxrwt  only the file's owner can delete it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;setuid is how passwd lets an ordinary user modify a root-owned file. It's also the first thing an attacker looks for:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
find / -perm -4000 -type f 2&amp;gt;/dev/null&lt;/p&gt;

&lt;p&gt;setgid on a directory is genuinely useful — it's the right way to build a shared directory:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
chgrp platform /srv/shared&lt;br&gt;
chmod 2775 /srv/shared&lt;/p&gt;

&lt;p&gt;Every file created there inherits the team's group. This is exactly what Kubernetes fsGroup does under the hood.&lt;/p&gt;

&lt;p&gt;Sticky bit is why /tmp is 1777 and not 777. Without it, any user could delete any other process's temp files.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;umask — why your file is born 644&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;umask is a mask that removes bits from the creation default.&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
$ umask&lt;br&gt;
0022&lt;br&gt;
umask   File (666−)   Directory (777−)&lt;br&gt;
022 644 755&lt;br&gt;
027 640 750&lt;br&gt;
077 600 700&lt;/p&gt;

&lt;p&gt;If a pipeline-generated file comes out with the wrong mode, the cause is almost always the umask of the process that created it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where this hits Kubernetes
yaml
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
runAsNonRoot: true
readOnlyRootFilesystem: true&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you understand the model:&lt;/p&gt;

&lt;p&gt;runAsUser sets the process UID. It does not need to exist in the image's /etc/passwd — the kernel only wants the number. That's why you see whoami: cannot find name for user ID 1000 in a container with no matching user: nothing is broken, there's just no number-to-name translation.&lt;br&gt;
fsGroup makes the kubelet apply that GID to mounted volumes and turn on setgid on the directory — exactly the mechanism from section 4. Without it, a volume owned by a different UID simply isn't writable.&lt;br&gt;
runAsNonRoot: true makes the kubelet refuse to start a container that would run as UID 0. Cheap and effective.&lt;/p&gt;

&lt;p&gt;And the classic trap: fsGroup does not work on NFS. NFS resolves permissions server-side, not client-side. If the export maps to a different UID, no securityContext will save you — the fix belongs on the NFS side.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The investigation checklist&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next time you hit Permission denied, follow this order instead of guessing:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
id                        # 1. who am I really (UID/GID, not name)&lt;br&gt;
ls -ln file               # 2. who owns it — -n shows numbers, not names&lt;br&gt;
namei -l /full/path       # 3. does the whole path allow traversal?&lt;br&gt;
stat file                 # 4. detailed mode, including special bits&lt;br&gt;
getfacl file              # 5. is an ACL overriding the classic model?&lt;/p&gt;

&lt;p&gt;Use ls -ln (with n) instead of ls -l when debugging containers. Seeing the number is what reveals the mismatch — the name hides it.&lt;/p&gt;

&lt;p&gt;If all five come back clean and it still denies, look one layer up — SELinux or AppArmor:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
getenforce&lt;br&gt;
ausearch -m avc -ts recent&lt;br&gt;
Exercise&lt;/p&gt;

&lt;p&gt;Five minutes, on a throwaway box or container:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
mkdir -p /tmp/lab &amp;amp;&amp;amp; cd /tmp/lab&lt;br&gt;
touch public.txt private.txt&lt;br&gt;
chmod 644 public.txt&lt;br&gt;
chmod 600 private.txt&lt;br&gt;
mkdir shared &amp;amp;&amp;amp; chmod 2775 shared&lt;br&gt;
ls -ln&lt;br&gt;
stat shared | head -5&lt;br&gt;
umask&lt;/p&gt;

&lt;p&gt;Then answer without looking:&lt;/p&gt;

&lt;p&gt;Why can't a user in the same group read private.txt?&lt;br&gt;
What does the 2 in 2775 change about shared?&lt;br&gt;
With umask 0022, what mode does a new directory get?&lt;/p&gt;

&lt;p&gt;If all three come easily, you understand the model — you didn't memorize the numbers.&lt;/p&gt;

&lt;p&gt;This is part #4 of the Linux from Zero track — free, open material for people building a solid foundation before taking on platform work and Kubernetes.&lt;/p&gt;

&lt;p&gt;Full repository: kubernetes-do-zero-ptbr&lt;/p&gt;

</description>
      <category>linux</category>
      <category>kubernetes</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Linux From Zero Networking, DNS, Ports and Sockets for Platform Engineers</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Mon, 31 Aug 2026 17:12:12 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/linux-from-zero-networking-dns-ports-and-sockets-for-platform-engineers-240h</link>
      <guid>https://dev.to/rogeroliveira86/linux-from-zero-networking-dns-ports-and-sockets-for-platform-engineers-240h</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6830v4m9nrtslls33818.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6830v4m9nrtslls33818.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first two posts of this series we covered the terminal, files, permissions, processes and systemd. By now you can look at a Linux box and understand &lt;strong&gt;what's running&lt;/strong&gt; and &lt;strong&gt;who's allowed to touch what&lt;/strong&gt;. What's missing is the piece that shows up in almost every real incident: networking.&lt;/p&gt;

&lt;p&gt;My thesis for this series stays the same: &lt;strong&gt;Platform Engineering starts before Kubernetes.&lt;/strong&gt; Before you debug a &lt;code&gt;CrashLoopBackOff&lt;/code&gt; or an &lt;code&gt;Ingress&lt;/code&gt; that won't resolve, you need to know how to investigate networking on the bare operating system. Without that, troubleshooting is just guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Linux sees a network interface
&lt;/h2&gt;

&lt;p&gt;Every conversation starts with an interface. On modern systems, the reference tool is &lt;code&gt;ip&lt;/code&gt;, not the old &lt;code&gt;ifconfig&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows interfaces (&lt;code&gt;lo&lt;/code&gt;, &lt;code&gt;eth0&lt;/code&gt;, &lt;code&gt;ens160&lt;/code&gt;, container/bridge interfaces like &lt;code&gt;docker0&lt;/code&gt; or &lt;code&gt;cni0&lt;/code&gt;), assigned IPs, and state (&lt;code&gt;UP&lt;/code&gt;/&lt;code&gt;DOWN&lt;/code&gt;). To understand where traffic actually goes, the routing table is next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip route
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default route (&lt;code&gt;default via ...&lt;/code&gt;) decides where a packet goes when no more specific route matches. On platforms with multiple interfaces (production, management, storage), one of the most common operational mistakes is assuming traffic leaves through one interface when the routing table actually sends it through another.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS: the most underrated cause of "it's down"
&lt;/h2&gt;

&lt;p&gt;A huge share of incidents that look like "the app is down" are actually name resolution failures. The basic flow on Linux goes through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the local resolver, historically configured in &lt;code&gt;/etc/resolv.conf&lt;/code&gt; (on many modern distros, now managed by &lt;code&gt;systemd-resolved&lt;/code&gt; or &lt;code&gt;NetworkManager&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;the lookup order defined in &lt;code&gt;/etc/nsswitch.conf&lt;/code&gt; (local &lt;code&gt;/etc/hosts&lt;/code&gt; before or after DNS, depending on configuration);&lt;/li&gt;
&lt;li&gt;the DNS server actually queried, which in corporate environments is usually an internal DNS with forwarders to the internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three commands solve 90% of DNS investigations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig example.com
dig example.com +trace
resolvectl status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dig +trace&lt;/code&gt; is the most underused one: it shows the full resolution path, from the root servers down to the final answer, and usually exposes exactly where the chain broke — a dead forwarder, an expired cache TTL, a record that no longer exists.&lt;/p&gt;

&lt;p&gt;A pattern worth memorizing: &lt;strong&gt;"I can't ping the name, but I can ping the IP" is almost always DNS, never networking.&lt;/strong&gt; Plenty of engineers waste time looking at firewalls and routes when the whole problem is name resolution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ports, sockets, and what "LISTEN" actually means
&lt;/h2&gt;

&lt;p&gt;A socket is the meeting point between a process and the network — a (IP address, port, protocol) tuple the kernel uses to hand packets to the right process. To see this live:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; and &lt;code&gt;-u&lt;/code&gt; show TCP and UDP sockets;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-l&lt;/code&gt; shows only the ones &lt;strong&gt;listening&lt;/strong&gt; — accepting new connections;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; shows the owning process;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt; skips name resolution, keeping the output fast and literal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gap between a service "listening" and a service "actually accepting connections" is where a lot of platform bugs live: a process can be &lt;code&gt;LISTEN&lt;/code&gt;ing on the right port and still refuse a connection because it's bound only to &lt;code&gt;127.0.0.1&lt;/code&gt; (loopback) while the client comes from a different interface, or because a firewall rule drops the packet before it even reaches the process.&lt;/p&gt;

&lt;p&gt;For TCP connection states (&lt;code&gt;SYN_SENT&lt;/code&gt;, &lt;code&gt;ESTABLISHED&lt;/code&gt;, &lt;code&gt;TIME_WAIT&lt;/code&gt;, &lt;code&gt;CLOSE_WAIT&lt;/code&gt;), &lt;code&gt;ss -tan&lt;/code&gt; gives the full picture — and an abnormal pile-up of &lt;code&gt;CLOSE_WAIT&lt;/code&gt;, for example, usually points to an application not closing connections properly, not to a networking issue at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  A troubleshooting checklist I actually use
&lt;/h2&gt;

&lt;p&gt;When a service "won't connect," the order that wastes the least time is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is the port actually listening?&lt;/strong&gt; (&lt;code&gt;ss -tulpn&lt;/code&gt; on the service's host)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On which interface?&lt;/strong&gt; (&lt;code&gt;0.0.0.0&lt;/code&gt; vs &lt;code&gt;127.0.0.1&lt;/code&gt; binding explains half of "works locally, not remotely")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does the name resolve to the right IP?&lt;/strong&gt; (&lt;code&gt;dig&lt;/code&gt;, compared against what you expect)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does a route to the destination exist?&lt;/strong&gt; (&lt;code&gt;ip route get &amp;lt;destination-ip&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is a firewall/security-group rule dropping the packet somewhere in between?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does the TCP handshake actually complete?&lt;/strong&gt; (&lt;code&gt;ss -tan&lt;/code&gt; on the client side during the connection attempt)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That sequence — port → bind → DNS → route → firewall → handshake — is an evidence-based investigation, not a guess. It's the same principle behind this whole series: you don't guess where the problem is, you eliminate one layer at a time until only one explanation is left.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters beyond plain Linux
&lt;/h2&gt;

&lt;p&gt;This entire toolkit reappears, almost untranslated, inside Kubernetes: &lt;code&gt;ClusterIP&lt;/code&gt; and &lt;code&gt;Service&lt;/code&gt; objects are, underneath, &lt;code&gt;iptables&lt;/code&gt;/&lt;code&gt;ipvs&lt;/code&gt; rules doing the exact same job of routing a packet to the right socket; &lt;code&gt;CoreDNS&lt;/code&gt; is the same name-resolution problem, just running inside the cluster; an &lt;code&gt;Ingress&lt;/code&gt; that won't respond usually boils down to the same six steps above, with one more layer of abstraction on top.&lt;/p&gt;

&lt;p&gt;Engineers who understand networking and sockets at the OS level debug Kubernetes with evidence. Engineers who don't just memorize &lt;code&gt;kubectl&lt;/code&gt; commands and hope for the best.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is the third post in the Linux From Zero series. Previous posts cover terminal/files/permissions and processes/systemd — hands-on labs live in the &lt;a href="https://github.com/roger-oliveira86/kubernetes-do-zero-ptbr" rel="noopener noreferrer"&gt;kubernetes-do-zero-ptbr&lt;/a&gt; repository. Next up: SSH and remote administration.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>networking</category>
      <category>devops</category>
      <category>sre</category>
    </item>
    <item>
      <title>Connection refused" has three different root causes here's how to tell them apart with evidence</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:04:11 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/connection-refused-has-three-different-root-causes-heres-how-to-tell-them-apart-with-evidence-166f</link>
      <guid>https://dev.to/rogeroliveira86/connection-refused-has-three-different-root-causes-heres-how-to-tell-them-apart-with-evidence-166f</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6jmj6jm97n1e2qnhypn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6jmj6jm97n1e2qnhypn.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connection refused" and a silent timeout look like the same failure to whoever's paging you at 2am. They're not. They come from different layers of the stack, and conflating them is why people restart services without ever fixing the actual cause.&lt;/p&gt;

&lt;p&gt;The mental model:&lt;/p&gt;

&lt;p&gt;Name (DNS) → Route to IP → Port open on target → Filter in the path → App responds&lt;/p&gt;

&lt;p&gt;Reproduce it yourself (Docker required):&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
docker network create rede-lab&lt;br&gt;
docker run -d --name servidor --network rede-lab nginx:alpine&lt;br&gt;
docker run -it --name cliente --network rede-lab busybox sh&lt;/p&gt;

&lt;p&gt;Then break each layer independently:&lt;/p&gt;

&lt;p&gt;DNS broken — overwrite /etc/resolv.conf inside the client container. Symptom: name doesn't resolve, but the same request by raw IP succeeds. That's your evidence it's DNS, not the network.&lt;br&gt;
Port closed — stop nginx but keep the container alive. Symptom: immediate Connection refused. Evidence: ss -tlnp on the server shows nothing listening on port 80.&lt;br&gt;
Firewall dropping — add an iptables -A INPUT -p tcp --dport 80 -j DROP rule. Symptom: silent timeout, no error. Evidence: tcpdump shows the SYN going out with no SYN-ACK coming back.&lt;/p&gt;

&lt;p&gt;Reference table:&lt;/p&gt;

&lt;p&gt;Symptom Likely cause    Confirming evidence&lt;br&gt;
Name doesn't resolve    DNS Direct IP access works&lt;br&gt;
Immediate refusal   Port closed ss -tlnp shows nothing listening&lt;br&gt;
Silent timeout  Firewall DROP   tcpdump shows unanswered SYN&lt;br&gt;
Timeout with RST    Firewall REJECT / closed port at OS level   RST visible in tcpdump&lt;/p&gt;

&lt;p&gt;The same three failure modes show up, renamed, in Kubernetes: DNS → misconfigured CoreDNS, closed port → empty Service Endpoints, firewall → a NetworkPolicy silently dropping traffic. Same method, different label.&lt;/p&gt;

&lt;p&gt;Full write-up with the "why it matters for platform/SRE work" framing and the GitHub reference chapter (with an exercise checklist) are linked above.&lt;/p&gt;

&lt;p&gt;Curious how people here debug this in practice: do you reach for tcpdump early, or only after ss/dig/nc rule out the obvious layers? And has anyone had a case where the symptom actively lied — e.g., a REJECT rule dressed up to look like a closed port? Drop it in the comments, I'm collecting real-world edge cases for the next chapter on containers.&lt;/p&gt;

</description>
      <category>inux</category>
      <category>networking</category>
      <category>devops</category>
      <category>platformengineering</category>
    </item>
    <item>
      <title>Platform Engineering starts before Kubernetes</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Fri, 21 Aug 2026 19:42:38 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/platform-engineering-starts-before-kubernetes-3ja1</link>
      <guid>https://dev.to/rogeroliveira86/platform-engineering-starts-before-kubernetes-3ja1</guid>
      <description>&lt;p&gt;&lt;em&gt;Why the right question isn't "where do I start with Kubernetes", but "what problem am I actually solving".&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The claim that tends to bother people
&lt;/h2&gt;

&lt;p&gt;Every time someone asks me "where do I start to become a Platform Engineer", the answer they expect is "Kubernetes". The answer I give is: no. Kubernetes is the tool you use once you already know what you're trying to solve. Platform Engineering is about the problem, not about the orchestrator.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually separates someone who "knows Kubernetes" from someone doing Platform Engineering
&lt;/h2&gt;

&lt;p&gt;After years running and evolving Kubernetes platforms in production — with hundreds of workloads and thousands of pods running in a regulated corporate environment — the difference I see in practice isn't in &lt;code&gt;kubectl&lt;/code&gt;. It's in three questions most tutorials never make you ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Who is your platform's customer?&lt;/strong&gt; It's not the cluster. It's the development team that needs to ship without pinging you every time. If you can't name who uses what you're building, you're operating infrastructure, not building a platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What happens when something breaks at 3am?&lt;/strong&gt; A tested rollback, a defined RTO, a clear incident owner — that's a design decision made long before any YAML manifest exists. A platform that wasn't designed to fail well, fails badly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How do you measure whether the platform is helping or getting in the way?&lt;/strong&gt; If the answer is "I don't know", you have a cluster, not a platform. Capacity planning, adoption metrics, reduced cross-team rework — that's what turns operations into an internal product.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where Linux comes in
&lt;/h2&gt;

&lt;p&gt;This is the connection the "Linux from Zero" series has been building since the first post: every abstraction Kubernetes gives you — pods, namespaces, resource limits, network policies — is an elegant repackaging of concepts that already exist in plain Linux: processes, kernel namespaces, cgroups, iptables/nftables. Once you understand the process before the pod, the kernel namespace before the Kubernetes namespace, you stop treating the cluster as a magic black box and start debugging like someone who understands the engine, not just the dashboard.&lt;/p&gt;

&lt;p&gt;It's not a coincidence that the worst production incidents I've had to solve had their root cause one layer below Kubernetes — disk I/O, DNS, kernel limits — not in the orchestrator itself. Someone who only knows how to operate Kubernetes is blind exactly where the problem lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  The path I advocate for (and the one this series follows)
&lt;/h2&gt;

&lt;p&gt;Linux → processes → networking → containers → Docker → containerd → Kubernetes → observability → SRE → Platform Engineering → architecture.&lt;/p&gt;

&lt;p&gt;That order isn't arbitrary. It's the order that gives you solid ground before it gives you altitude. Each layer explains the one above it. Jumping straight to "Kubernetes from zero" is like learning to fly a plane without understanding what makes it fly — you can memorize the controls, but you can't diagnose it when something goes off-script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this takes you in practice
&lt;/h2&gt;

&lt;p&gt;If you're trying to move from operations into Platform Engineering — or from Platform Engineer to Staff/Principal — the real test isn't "how many YAML manifests have you written". It's: can you explain, in one sentence, to a non-technical executive, why the platform you're building reduces risk and speeds up delivery? If yes, you're already thinking like a Platform Engineer. Kubernetes is just the tool you chose to execute that vision today — tomorrow it might be something else.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Full track (free, in Portuguese): &lt;a href="https://github.com/roger-oliveira86/kubernetes-do-zero-ptbr" rel="noopener noreferrer"&gt;github.com/roger-oliveira86/kubernetes-do-zero-ptbr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Agree or disagree? Curious to hear whether, in your experience too, the worst incidents also started "one layer below" Kubernetes.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>devops</category>
      <category>infrastructure</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Linux from Zero #2 Processes: what's actually running under your terminal</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Fri, 21 Aug 2026 19:40:58 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/linux-from-zero-2-processes-whats-actually-running-under-your-terminal-1a0f</link>
      <guid>https://dev.to/rogeroliveira86/linux-from-zero-2-processes-whats-actually-running-under-your-terminal-1a0f</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 2 of the "Linux from Zero" series. If you haven't read #1 yet, it's on Medium and DEV.to — start there to understand the approach: investigate through evidence, not by memorizing commands.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem nobody explains properly
&lt;/h2&gt;

&lt;p&gt;Have you ever run &lt;code&gt;ps aux&lt;/code&gt; and watched a huge list of lines scroll by, without really knowing what to do with it? Most tutorials teach you the command, but not how to &lt;em&gt;think&lt;/em&gt; about what it returns. This post is about exactly that: turning a list of numbers into reasoning about what your machine is actually doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The experiment
&lt;/h2&gt;

&lt;p&gt;Open two terminals side by side. In the first one, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;300 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a process that just "sleeps" for 300 seconds — doing nothing useful, on purpose, so it can be our test subject.&lt;/p&gt;

&lt;p&gt;In the second terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-eo&lt;/span&gt; pid,ppid,stat,etime,cmd | &lt;span class="nb"&gt;grep sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see a line similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;  PID   PPID STAT     ELAPSED CMD
12345   9876 S           0:03 sleep 300
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the question that actually matters: &lt;strong&gt;what is each of these columns telling you about this process's life?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PID&lt;/code&gt; — the unique identity of this process for as long as it exists.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PPID&lt;/code&gt; — who created this process (the parent process). In your case, probably the shell in your first terminal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;STAT&lt;/code&gt; — the current state. &lt;code&gt;S&lt;/code&gt; means "sleeping" (interruptible). You'll see &lt;code&gt;R&lt;/code&gt; (running), &lt;code&gt;Z&lt;/code&gt; (zombie), and &lt;code&gt;D&lt;/code&gt; (uninterruptible I/O wait) in other contexts — each one tells a different story about what is or isn't blocking the system.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ETIME&lt;/code&gt; — how long it's been alive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this actually matters
&lt;/h2&gt;

&lt;p&gt;In production, nobody runs &lt;code&gt;sleep&lt;/code&gt; on purpose — but every performance incident I've ever investigated started with exactly this question: "which processes are running, who's the parent of what, and what state are they stuck in?". A process stuck in &lt;code&gt;D&lt;/code&gt; state (uninterruptible sleep) for a long time, for example, is almost always a symptom of a disk or storage problem — not an application bug.&lt;/p&gt;

&lt;p&gt;Now try killing the process through its parent, not the &lt;code&gt;sleep&lt;/code&gt; itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-TERM&lt;/span&gt; &amp;lt;your_shell_PPID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Don't actually run this in your main terminal&lt;/strong&gt; — it's just so you can mentally picture what would happen: killing the parent process usually kills the &lt;code&gt;sleep&lt;/code&gt; child too (or it gets "adopted" by &lt;code&gt;init&lt;/code&gt;/&lt;code&gt;systemd&lt;/code&gt;, depending on the system). This reparenting behavior is the same logic behind why, when a container dies unexpectedly, the processes it was hosting disappear along with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bridge to where this series is going
&lt;/h2&gt;

&lt;p&gt;This parent/child relationship between processes is exactly what Linux uses as the foundation for isolating processes into namespaces — the mechanism that, later in this series, becomes containers, and that Kubernetes orchestrates at scale. Understanding processes today, without rushing, is what makes the "aha" moment happen when you get to &lt;code&gt;cgroups&lt;/code&gt; and &lt;code&gt;namespaces&lt;/code&gt; a couple of posts from now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Before the next post, try answering these on your own machine (no need to reply here, this one's for you):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;ps -eo pid,ppid,stat,etime,cmd --forest&lt;/code&gt; and visually identify which process is the parent of which.&lt;/li&gt;
&lt;li&gt;Find (or fail to find) a process in &lt;code&gt;Z&lt;/code&gt; (zombie) state — if you don't find one, that's already useful information: your system is healthy on that front right now.&lt;/li&gt;
&lt;li&gt;Compare &lt;code&gt;ps aux&lt;/code&gt; with &lt;code&gt;top&lt;/code&gt; (or &lt;code&gt;htop&lt;/code&gt;) running at the same time — what changes between a static snapshot and a continuous view?&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;Next in the series: namespaces, and what actually isolates one process from another — the foundation of everything we now call a "container".&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Full track (free, in Portuguese): &lt;a href="https://github.com/roger-oliveira86/kubernetes-do-zero-ptbr" rel="noopener noreferrer"&gt;github.com/roger-oliveira86/kubernetes-do-zero-ptbr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Have you ever run into a process stuck in &lt;code&gt;D&lt;/code&gt; state during a real incident? What caused it? I'm collecting real-world examples for the next posts in this series — drop them in the comments.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Linux from Zero #1: What Is Linux and Which Distribution Should You Choose?</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Mon, 17 Aug 2026 23:31:30 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/upload-cover-imageno-file-chosenuse-a-ratio-of-1000420-for-best-results-generate-image-cover-2kbc</link>
      <guid>https://dev.to/rogeroliveira86/upload-cover-imageno-file-chosenuse-a-ratio-of-1000420-for-best-results-generate-image-cover-2kbc</guid>
      <description>&lt;h1&gt;
  
  
  Linux from Zero #1: What Is Linux and Which Distribution Should You Choose?
&lt;/h1&gt;

&lt;p&gt;When people start studying DevOps, SRE, or Kubernetes, they usually find a long list of tools. But there is a layer underneath all of them: the operating system.&lt;/p&gt;

&lt;p&gt;If you do not understand processes, permissions, services, networking, and logs, every container or cluster error can feel mysterious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which distribution should you choose?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ubuntu LTS
&lt;/h3&gt;

&lt;p&gt;My recommendation for a first lab. It has a large community, extensive learning material, and is widely used in cloud environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debian Stable
&lt;/h3&gt;

&lt;p&gt;A strong choice for learning a stable server foundation and the Debian ecosystem. Use it after your first contact with Linux.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>kubernetes</category>
      <category>sre</category>
    </item>
    <item>
      <title>Kubernetes from Scratch What It Is, How to Avoid Crashing Your PC, and Creating Your First Pod</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Tue, 11 Aug 2026 12:34:35 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/-kubernetes-from-scratch-what-it-is-how-to-avoid-crashing-your-pc-and-creating-your-first-pod-3olg</link>
      <guid>https://dev.to/rogeroliveira86/-kubernetes-from-scratch-what-it-is-how-to-avoid-crashing-your-pc-and-creating-your-first-pod-3olg</guid>
      <description>&lt;p&gt;&lt;em&gt;How to understand the world's most famous orchestrator using the cargo ship analogy — and run your first lab 100% in your browser.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are starting out in IT, migrating to DevOps, or looking to advance toward technical leadership roles (such as &lt;em&gt;Staff/Principal Engineer&lt;/em&gt;), the word &lt;strong&gt;Kubernetes&lt;/strong&gt; crosses your path every single day.&lt;/p&gt;

&lt;p&gt;However, the first barrier is almost always the same: &lt;strong&gt;"Where do I start without drowning in heavy theory and without freezing my computer?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this first article of the &lt;strong&gt;Kubernetes from Scratch&lt;/strong&gt; series, we will demystify core concepts using real-world analogies, understand the basic architecture, and launch your first live application in less than 5 minutes — completely free and directly inside your browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Core Analogy: The Automated Port 🚢
&lt;/h2&gt;

&lt;p&gt;To understand Kubernetes, you don't need complex jargon. Think of &lt;strong&gt;global maritime logistics&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Application (Your Code):&lt;/strong&gt; This is the goods needing delivery (e.g., an e-commerce store or a banking system).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Container (Docker):&lt;/strong&gt; This is the standardized metal cargo box. It doesn't matter if there are shoes, electronics, or food inside: from the outside, the dimensions and locking mechanisms are universal. It runs the exact same way on your laptop as it does in the cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Pod:&lt;/strong&gt; This is the exact space (the rack or ship deck area) where one or more containers sit and work together. In Kubernetes, the Pod is the smallest unit you manage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes (The Port Captain):&lt;/strong&gt; This is the robotic conductor. If a cargo box falls into the sea (an application error), the Captain instantly creates a brand-new box in its place within seconds. If traffic surges during Black Friday, the Captain automatically requests more ships.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. The Golden Rule: Forget Local Clusters at First 💡
&lt;/h2&gt;

&lt;p&gt;One of the biggest mistakes beginners make is trying to install tools like &lt;em&gt;Minikube&lt;/em&gt; or &lt;em&gt;Kind&lt;/em&gt; on resource-constrained laptops. The computer freezes, the cooling fans go wild, and learning turns into frustration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; In the official CNCF exam (the &lt;strong&gt;CKA - Certified Kubernetes Administrator&lt;/strong&gt;) and in real-world production environments, work is done via a Linux terminal and a web browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why we use &lt;strong&gt;Killercoda&lt;/strong&gt; (&lt;code&gt;killercoda.com&lt;/code&gt;): a free platform that provides a real Kubernetes cluster running directly in the cloud through your browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Hands-On: Your First Pod in the Browser 🛠️
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="https://killercoda.com" rel="noopener noreferrer"&gt;killercoda.com/playgrounds&lt;/a&gt; and select the &lt;strong&gt;Kubernetes Playground&lt;/strong&gt; environment.&lt;/p&gt;

&lt;p&gt;Once the terminal screen loads, follow these 3 quick steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Terminal Survival Kit
&lt;/h3&gt;

&lt;p&gt;Whenever you start a new lab environment, set up an alias to save keystrokes and adjust the &lt;code&gt;.yaml&lt;/code&gt; file formatting for the &lt;code&gt;vim&lt;/code&gt; editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Shortcut for kubectl&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;kubectl

&lt;span class="c"&gt;# 2. Configure Vim to respect 2-space YAML indentation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"set tabstop=2 shiftwidth=2 expandtab"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.vimrc

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Spin Up an Application Imperatively
&lt;/h3&gt;

&lt;p&gt;Instead of writing dozens of lines of YAML manually from scratch, use imperative commands to generate resources quickly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a Pod running an NGINX web server&lt;/span&gt;
k run my-web &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx:alpine

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Inspect Your Resource
&lt;/h3&gt;

&lt;p&gt;Check if your Pod is up and running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k get pods

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the status shows &lt;code&gt;Running&lt;/code&gt;, congratulations! You have just placed your first container under Kubernetes orchestration.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. What To Do When Things Go Wrong? 🔍
&lt;/h2&gt;

&lt;p&gt;The most valuable skill in daily operations is &lt;strong&gt;Troubleshooting&lt;/strong&gt;. If your Pod fails to start, follow this investigation sequence in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Check the general status of the Pod&lt;/span&gt;
k get pods

&lt;span class="c"&gt;# 2. Inspect cluster events (WHAT happened?)&lt;/span&gt;
k describe pod my-web

&lt;span class="c"&gt;# 3. Analyze container logs (WHY did the application fail?)&lt;/span&gt;
k logs my-web

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📚 Next Steps &amp;amp; Official Sources
&lt;/h2&gt;

&lt;p&gt;This article is just the gateway. To deepen your learning in a structured way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Open-Source Repository:&lt;/strong&gt; All code, guides, and practical exercises from this series are hosted on GitHub: &lt;a href="https://github.com/roger-oliveira86/kubernetes-do-zero-ptbr" rel="noopener noreferrer"&gt;https://github.com/roger-oliveira86/kubernetes-do-zero-ptbr&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official Documentation (CNCF):&lt;/strong&gt; Get comfortable searching &lt;a href="https://kubernetes.io/docs" rel="noopener noreferrer"&gt;kubernetes.io/docs&lt;/a&gt; — it is your best friend in production and the only allowed reference material during certification exams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practice Platform:&lt;/strong&gt; Work through guided scenarios covering RBAC, Storage, and Troubleshooting at &lt;a href="https://killercoda.com" rel="noopener noreferrer"&gt;Killercoda&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  💬 What About You?
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;What was the biggest challenge you faced when you first tried to learn Kubernetes? Leave a comment below and share this article with anyone starting their Cloud Native journey!&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Kubernetes #DevOps #CloudNative #Docker #TechCommunity #CKA
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>What 9 articles in 15 months taught me about writing with consistency</title>
      <dc:creator>Roger Oliveira</dc:creator>
      <pubDate>Mon, 03 Aug 2026 22:57:56 +0000</pubDate>
      <link>https://dev.to/rogeroliveira86/o-que-9-artigos-em-15-meses-me-ensinaram-sobre-escrever-com-constancia-4kml</link>
      <guid>https://dev.to/rogeroliveira86/o-que-9-artigos-em-15-meses-me-ensinaram-sobre-escrever-com-constancia-4kml</guid>
      <description>&lt;p&gt;I have a strange publishing pattern. Five articles in four months. Then seven months of complete silence. Three articles in five weeks. Then almost three months of silence again. One article. And here I am, trying to understand what this pattern actually means before I simply promise "I'm going to post every week" and repeat the cycle.&lt;/p&gt;

&lt;p&gt;Between April and July 2025, I wrote about the fundamentals: a platform engineering study plan, the signs that an infrastructure needs modernization, the strategic role of someone who operates beyond technical execution, and the bridge between engineering and business. In the middle of all that, I also wrote about workplace burnout—not because I planned a "different" kind of article, but because it was what I had to say at that moment. That article, by the way, is still the one that represents me most from this first phase: it shows that consistency in producing technical content isn't incompatible with admitting that sometimes you just lack the energy to produce anything at all.&lt;/p&gt;

&lt;p&gt;Then, silence. Seven months.&lt;/p&gt;

&lt;p&gt;It wasn't for lack of topics. It was the kind of period where operations consume all the energy that would otherwise be left to reflect on them—and reflecting in writing requires a different kind of energy than resolving an incident.&lt;/p&gt;

&lt;p&gt;When I came back in March 2026, the tone had shifted. "Software Architecture is Actually Decision Management" is no longer about tools or warning signs—it's about how technical decisions carry consequences that survive far beyond those who made them. Two weeks later, "Systems Scale the Same Way Organizations Do" continues that line of thought: architecture isn't just code, it's decision structure. And three weeks after that, "You Don't Scale Systems While You Remain Their Central Point" hits the most uncomfortable point of the three—that sometimes, the bottleneck is me.&lt;/p&gt;

&lt;p&gt;Three dense articles in five weeks. And silence again—this time almost three months, until "Rollback Isn't a Backup Plan. It's a Culture." in July, written in English and targeting a broader audience than the previous ones.&lt;/p&gt;

&lt;p&gt;This isn't a pattern of laziness. It's a spike pattern: I write when a thought has matured enough to become a piece of writing, not at the artificial pace of an editorial calendar. The problem is that spikes are unpredictable—and unpredictability, for someone trying to build a consistent technical presence, is the opposite of what works.&lt;/p&gt;

&lt;p&gt;So the change I'm testing now isn't "writing more." It's reducing the step size: instead of waiting for a full article to mature, recording a single paragraph, an unformed idea, or an unanswered question—every week, not just when the spike hits. If it yields an article, great. If it doesn't, at least there's a trace showing that the thinking didn't stop during the silent months; it just wasn't ready for publication.&lt;/p&gt;

&lt;p&gt;If you also write in spikes, or have tried a cadence that didn't hold up—leave a comment below with what worked (or didn't) for you.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
