惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Security Affairs
PCI Perspectives
PCI Perspectives
Google Online Security Blog
Google Online Security Blog
W
WeLiveSecurity
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
P
Privacy & Cybersecurity Law Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity
TaoSecurity Blog
TaoSecurity Blog
V
Visual Studio Blog
博客园 - 聂微东
Scott Helme
Scott Helme
博客园 - 【当耐特】
K
Kaspersky official blog
Security Latest
Security Latest
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
MyScale Blog
MyScale Blog
Schneier on Security
Schneier on Security
WordPress大学
WordPress大学
博客园 - 叶小钗
C
Check Point Blog
V2EX - 技术
V2EX - 技术
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
T
Tor Project blog
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
雷峰网
雷峰网
博客园_首页
美团技术团队
Y
Y Combinator Blog
C
CERT Recently Published Vulnerability Notes
AWS News Blog
AWS News Blog
月光博客
月光博客
N
Netflix TechBlog - Medium
Last Week in AI
Last Week in AI
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
Help Net Security
Help Net Security
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
C
Cybersecurity and Infrastructure Security Agency CISA

Learn Cloud Native

Local development with coding agents on Kubernetes using Signadot | Learn Cloud Native cuenv: one typed file for your whole project | Learn Cloud Native Preflight: AI Code Review Before You Push Anatomy of AI Agents Accessing Google Drive from Next.js Deploying to Fly.io using Dagger and Github Top Cloud-Native & Kubernetes Certifications [2026 Guide] Rapid microservices development with Signadot How to prepare for Istio certified associate exam (ICA) Global Rate Limiting in Istio with Envoy Rate Limit Service My Journey with Istio: From Incubation to Graduation Cilium Network Policy Tutorial: Secure Kubernetes Step by Step Kubernetes Networking: How kube-proxy and iptables Work Istio ServiceEntry: DNS vs. STATIC Resolution & Endpoints Explained Apply an Istio DestinationRule Globally (Mesh-Wide) Istio Rate Limiting: Configure a Local Rate Limiter in Envoy How to expose custom ports on Istio ingress gateway Portainer Tutorial: A Web UI for Kubernetes & Containers Traefik Proxy 2.x and TLS 101 Kubernetes CLI (kubectl) tips you didn't know about Setting up SSL certificates with Istio Gateway ArgoCD Best Practices You Should Know 在 OCI Ampere A1 计算实例上运行 AI Running AI On OCI Ampere A1 Instance How to Deploy Traefik Proxy Using Flux and GitOps Principles Firebase Emulators with Next.js: Local Setup Guide Running Hugo on free Ampere VM (Oracle Cloud Infrastructure) How to use kwatch to detect crashes in Kubernetes clusters Continuous profiling in Kubernetes using Pyroscope Monitoring containers with cAdvisor Creating a Kubernetes cluster in Google Cloud (LAB) Your first Kubernetes Pod and ReplicaSet (LABS) Container Lifecycle Hooks Maybe Convert Wasm Extension Config? GetIstio - CLI, training, and community Attach multiple VirtualServices to Istio Gateway Kubernetes Volumes Explained: Keep Data Beyond the Pod Send a Slack message when Docker images are updated Kubernetes Network Policy Ambassador Container Pattern Start Kubernetes Release Sidecar Container Pattern Kubernetes Init Containers Deploying multiple Istio Ingress Gateways Branch by Abstraction Pattern The Strangler Pattern Securing Kubernetes Ingress with Ambassador and Let's Encrypt All About the Ingress Resource How to quarantine Kubernetes pods? Getting started with Kubernetes Horizontal partitioning in MongoDB Docker image tagging scheme Six things to keep in mind when working with Dockerfiles Beginners guide to Docker Beginners guide to gateways and proxies Deploy and Operate Multiple Istio Meshes in one Kubernetes Cluster Managing service meshes with Meshery Circuit Breaking in Istio Explained Build and push your Docker images using Github Actions Kubernetes and Istio service mesh workshop materials Build Netlify-like deployment for React app using Kubernetes pods Six exciting enhancements in Istio 1.4.0 Fallacies of Distributed Systems CAP Theorem Explained Master the Kubernetes CLI (kubectl) - Cheatsheet Minikube Basics and How to Get Started with Kubernetes 5 Tips to Be More Productive with Kubernetes What are sticky sessions and how to configure them with Istio? Debugging Kubernetes applications using Istio Kubernetes Ingress and Istio Gateway Resource Zero Downtime Releases using Kubernetes and Istio Traffic Mirroring with Istio Service Mesh Expose a Kubernetes service on your own custom domain
Kubernetes Development Environment with Skaffold
Peter Jausovec · 2020-07-12 · via Learn Cloud Native

One part of the Start Kubernetes course I am working on (in addition to the book and videos) is the interactive labs. The purpose of these labs is to help you learn Kubernetes by solving different tasks, such as creating pods, scaling deployments, and so on. What follows is a quick explanation of how the end-user experience looks like.

Start Kubernetes Labs Experience

Each task has a set of instructions and requirements. For example, here's how the web page looks like for one of the tasks in the Pods section:

The top part of the page explains what the task is and what you need to accomplish (e.g. create a Kubernetes Pod with a specific name and image).

The bottom portion is the actual terminal window where you can interact with your Kubernetes cluster. From this terminal, you have access to the Kubernetes CLI and other tools and commands you might need to solve the tasks.

To solve the task from the screenshot above you need to create a new Pod with the specified name and image. Once you do that you can click the VERIFY button - this will run the verification and make sure you completed the task correctly. In this case, it checks that the pod with the specified name is created, it uses the correct image and it is deployed in the correct namespace.

At the moment there are two pieces that make up the solution: the web frontend and the backend that runs the terminal I connect to from the frontend.\

Frontend

For the frontend, I picked TypeScript and React. I have been using Typescript for the past couple of months and I really like it. If you're coming from the Javascript world, it does take a bit to get used to it, but the switch is definitely worth it. Typescript is nothing but Javascript, but it has additional features on top - stuff like types, static typing, and generics.

Like with my other projects, I am using Tailwind CSS. I still think I am 'wasting' way too much time playing with the design, but with Tailwind, I am at least constrained in terms of which colors to use, uniform margins/padding etc. And before anyone says something, yes, I know, you can overwrite and customize Tailwind to include whatever you want, but I am fine with the defaults at the moment.

Backend

On the backend, I am using Typescript and Express. I am creating an instance of the pseudo-terminal (node-pty) and connecting to it using a web socket and the AttachAddon for xterm.js. When initializing the attach addon, you can pass in the web socket. That creates the connection from the terminal UI in the frontend to the pseudo-terminal running on the backend.

The backend code is fairly straightforward at the moment. The pseudo-terminal listens on the data event and sends the data through the web socket back to the frontend. Similarly, whenever there's a message on the web socket (coming from the frontend), the data gets sent to the pseudo-terminal.

This means that I am actually getting a terminal inside of the Docker image where the backend is running. It's far from perfect, but it is a start. A much better solution would be to run a separate container whenever a terminal is requested.

Since everything is running inside a Kubernetes cluster, the terminal that gets initialized in the backend container has access to the cluster. Note that this is not in any way secure and it is only meant to be running in your local cluster. There are ways to isolate the terminal user to be only able to execute certain commands or have access to a single cluster etc.

An even better solution would be to isolate the terminals from everything. That means that the frontend and backend don't have to run inside Kubernetes at all. Whenever a terminal is requested a new VM could be allocated by the backend. This would allow for complete separation of everything. Even if a malicious actor gets access to the VM, they don't have access to anything else and the VM gets terminated.

Here's a quick diagram on how this could work (it's probably way more complicated than it looks like):

The logic for VM management would have to be smart. You could probably keep a pool for VMs that are ready to go, so you can just turn them on, send back the VM information, and users can connect to the terminal. The upside with this approach is that you could have different VM images prepared (with different stuff installed on them), you can bring up multiple VMs and simulate more complex scenarios etc. However, the downside is that it is way more complex to implement and it costs $$ to keep a pool of VMs running. It would definitely be an interesting solution to implement.

Dev Environment Setup

Back to the real world and my local environment setup. As mentioned previously I am running both components (frontend and backend) in the Kubernetes cluster. I could have run both of them just locally, outside of the cluster - the terminal that would get allocated would be on my local machine, thus it would have access to the local cluster. However, I wanted to develop this in the same way it would be running when installed - i.e. everything inside of the cluster.

I am using Skaffold to automatically detect the source code changes in both components, rebuild the images, and update the deployments/pods in the cluster. At first, I was a bit skeptical that it would take too long, but I must say it doesn't feel like it's too slow to refresh/rebuild.

Docker files

To set it up, I started with the Docker images for both projects. In both cases, the Dockerfiles were 'development' Docker files. That means I am running nodemon for the server project and the default react-scripts start for the frontend.

Here's how the Dockerfile for the React frontend looks like:

FROM node:alpine

WORKDIR /app
EXPOSE 3000
CMD ["npm", "run", "start"]
ENV CI=true
COPY package* ./
RUN npm ci
COPY . .

Kubernetes Deployment files

The next step was to create the Kubernetes YAML files for both projects. There's nothing special in the YAML files - they are just Deployments that reference an image name (e.g. startkubernetes-web or ws-server) and define the ports both applications are available on.

With these files created, you can run skaffold init. Skaffold automatically scans for Dockerfiles and Kubernetes YAML files and asks you the questions to figure out which Dockerfile to use for the image referenced in the Kubernetes YAML files.

Once that's determined it creates a Skaffold configuration file in skaffold.yaml. This is how the Skaffold configuration file looks like:

apiVersion: skaffold/v2beta5
kind: Config
metadata:
  name: startkubernetes-labs
build:
  artifacts:
    - image: startkubernetes-web
      context: web
    - image: ws-server
      context: server
deploy:
  kubectl:
    manifests:
      - server/k8s/deployment.yaml
      - web/k8s/deployment.yaml

In the section under the build key you notice the image names (from the YAML files) and the contexts (folders) to use to build these images. Similarly, the deploy section lists the manifests to deploy using Kubernetes CLI (kubectl).

Now you can run skaffold dev to enter the development mode. The dev command builds the images and deploy the manifests to Kubernetes. Running the kubectl get pods shows you the running pods:

$ kubectl get po
NAME                        READY   STATUS    RESTARTS   AGE
web-649574c5cc-snp9n        1/1     Running   0          49s
ws-server-97f8d9f5d-qtkrg   1/1     Running   0          50s

There are a couple of things missing though. First, since we are running both components in dev mode (i.e. automatic refresh/rebuild) we need to tell Skaffold to sync the changed files to the containers, so the rebuild/reload is triggered. Second, we can't access the components as they are not exposed anywhere. We also need to tell Skaffold to expose them somehow.

File sync

Skaffold supports copying changed files to the container, without rebuilding it. Whenever you can avoid rebuilding an image is a good thing as you are saving a lot of time.

The files you want to sync can be specified under the build key in the Skaffold configuration file like this:

build:
  artifacts:
    - image: startkubernetes-web
      context: ./web
      sync:
        infer:
          - '**/*.ts'
          - '**/*.tsx'
          - '**/*.css'
    - image: ws-server
      context: ./server
      sync:
        infer:
          - '**/*.ts'

Notice the matching pattern monitors for all .ts, .tsx and .css files. Whenever any file that matches that pattern changes, Skaffold will sync the files over to the running container and nodemon/React scripts will detect the changes and reload accordingly.

Exposing ports

The second thing to solve is exposing ports and getting access to the services. This can be defined in the port forward section of the Skaffold configuration file. You define the resource type (e.g. Deployment or Service), resource name, and the port number. Skaffold does the rest and ensures that those services get exposed.

portForward:
  - resourceType: deployment
    resourceName: web
    port: 3000
  - resourceType: service
    resourceName: ws-server
    port: 8999

Now if you run the skaffold dev --port-forward the Skaffold will rebuild what's needed and set up the port forward based on the configuration. Here's the sample output of the port forward:

Port forwarding deployment/web in namespace default, remote port 3000 -> address 127.0.0.1 port 3000
Port forwarding service/ws-server in namespace default, remote port 8999 -> address 127.0.0.1 port 8999

Conclusion

If you are doing any development for Kubernetes, where you need to run your applications inside the cluster, make sure you take a look at Skaffold. It makes everything so much easier. You don't need to worry about rebuilding images, syncing files and re-deploying - it is done all for you.

If you liked this article you will definitely like my new course called Start Kubernetes. This course includes everything I know about Kubernetes in an ebook, set of videos and practial labs.

I am always eager to hear your questions and comments. You can reach me on Twitter or send me a message.

If you are interested in more articles and topics like this one, make sure you sign up for my newsletter.